这个问题可能听起来很愚蠢,但我并不确定。 我的意思是,有什么区别:
char* line = (char*) malloc(MAX_LINE_LEN);
和
char line[MAX_LINE_LEN];
究竟? 我知道前者是一个指针而后者是一个数组,但系统如何区分呢? 如何分配/存储内存?
另外,为什么可以在声明为指针时删除line
占用的内存,而不是当它是数组时? 我认为数组存储在其他地方,系统会在超出范围时自动释放内存,这在处理指针时不会发生,所以你必须自己删除它。 我错了吗?
char* line = (char*) malloc(MAX_LINE_LEN);
这种风格很差; 你不需要在C中malloc
。让我们把它分成两部分,因为它更容易描述和比较:
char *line;
声明一个指向char命名line
的指针。 您可以将其指定为指向对象(或不指向任何对象)。 对象的大小是它的类型的大小,因此sizeof (line)
是sizeof (char *)
,因系统而异。 &line
是char *
的地址,其类型为char **
(指向char的指针)。 它的存储持续时间取决于它的声明位置:
您的初始化为其分配了一个值,因此无论如何它都不会开始不确定。 malloc
返回一个指向具有动态存储持续时间的对象的指针,这意味着指针指向的对象将持续存在,直到它明确free
为止。
想想这一 line
就像邮件信封上的邮政编码一样; 你可以在那里写一些东西,这些东西将指示你可以找到对象(和人)的位置。 邮政编码不会告诉您有关对象(或人员)大小的任何信息。
char line[MAX_LINE_LEN];
这声明了一个MAX_LINE_LEN
字符数组。
类型为char[MAX_LINE_SIZE]
,因此大小将为sizeof (char[MAX_LINE_SIZE])
,反映为您可以通过指定的元素数量查看。 在这种情况下, &line
的地址是char (*)[MAX_LINE_SIZE]
(指向MAX_LINE_SIZE
字符数组的指针)。
这个不能像上面那样重新分配,因此它与我们的邮政编码示例不同。 当数组用于编译器需要指针的位置时,该数组将被隐式转换为指向第一个元素的指针。 例如,让我们考虑一下:
strcpy(line, "Hello, world!");
函数原型char *strcpy(char *restrict s1, const char *restrict s2);
,告诉我们strcpy
接受两个char *
( 指向char的指针 )参数。 在该示例中,其中一个参数是char[MAX_LINE_LEN]
,另一个是char[14]
。 两者都转换为char *
。
这个数组到指针的转换解释了为什么char *line; line = "hello";
char *line; line = "hello";
有效,而char line[MAX_LINE_LEN]; line = "hello";
char line[MAX_LINE_LEN]; line = "hello";
不是。 您无法更改转换产生的指针。
我知道前者是一个指针而后者是一个数组,但系统如何区分呢?
如前所述,当数组表达式在预期指针的位置使用时,它将转换为指针表达式。 例如, array
array[x]
中的array[x]
转换为pointer[x]
中的pointer[x]
。 你在问什么? 为什么需要知道数组和指针之间的区别?
我认为数组存储在其他地方,当系统超出范围时,系统会自动释放内存,
是。 我之前解释了不同的存储持续时间。
当你处理指针时不会发生这种情况,所以你必须自己删除它。 我错了吗?
是。 你将指针的概念与存储持续时间的概念混淆了。 int *p = malloc(sizeof *p);
p被初始化为指向具有动态存储持续时间的int
。 直到free(p);
int
才会被销毁free(p);
叫做。 但是,下面的两个变量都具有自动存储持续时间,因为它们在main
声明,没有任何限定符,例如static
。 p
指向i
; p
是一个指针。 不要free
p,因为它不指向具有动态存储持续时间的对象。 free
仅定义为销毁具有动态存储持续时间的对象。
int main(void) { int i = 42; int *p = &i; }
char* line;
在堆栈上分配指针。 当程序计数器超出本声明的范围时,它将自动释放。
line = (char*) malloc(MAX_LINE_LEN);
在堆上动态分配MAX_LINE_LEN
个字节。 确切地说,您应该以这种方式使用malloc
:
line = malloc(MAX_LINE_LEN * sizeof(char));
稍后你应该调用free(line)
来释放这个堆内存。
sizeof(line)
将返回指针占用的字节数(通常为4或8个字节)。
char line[MAX_LINE_LEN];
在堆栈上分配MAX_LINE_LEN
字符。 当程序计数器超出本声明的范围时,它将自动释放。
sizoef(line)
将返回MAX_LINE_LEN * sizeof(char)
字节。
可能是理解这一点的最佳资源是comp.lang.c FAQ 。
实际上,区别在于sizeof
运算符的效果。 sizeof(pointer)
给出sizeof(pointer)
的大小,而sizeof(array)
给你……你猜对了。
当作为函数参数传递时,数组名称会衰减为指向第一个元素的指针(丢失sizeof
信息)。 在正常表达式中,它的行为就像它衰减到指针一样,因为数组语法是根据等效指针操作定义的。 (事实上,早期的C编译器声明了带有identifier[]
指针。)
A[X]
根据定义,它完全等同于
*(A + X)
需要注意的是,在A[X]
, A
或X
( 任何一个 ) 中的一个必须是指针或数组。
答案就在那里,堆和堆栈问题。
数组,指针,局部变量是堆栈对象,而堆对象是使用malloc / free方法。
只需看一下堆栈和堆的内容和位置? 详情。
需要了解更多c/c++开发分享C中的数组和指针有什么区别?,也可以关注C/ C++技术分享栏目—计算机技术网(www.ctvol.com)!
以上就是c/c++开发分享C中的数组和指针有什么区别?相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/979025.html