c中的数组声明
可能重复:
堆栈变量与堆变量
声明数组之间的区别是:
int arr[100];
和
int* arr=(int*)malloc(sizeof(int)*100);
哪一个更受欢迎? 有没有像堆和堆栈内存这样的东西?
我建议去书店去买一本Kernighan和Ritchie的C编程语言 ,还可以选一本Harbison&Steele的C:A参考手册 。
第一种情况为您提供了一个100个整数的数组,在堆栈上分配。 后一种情况为您提供了一个指向int的指针,其地址是在堆上分配的缓冲区的地址,其大小足以容纳100个int。
C语言基本上是一种与硬件无关的汇编语言。 指针和数组之间的区别是有意模糊的,因为数组引用符号是指针算术的语法糖。 这个:
int foo( int a ) { int x[100] = load_X() ; int y = x[ a ] ; return y ; }
是完全相同的
int foo( int a ) { int *x = load_X() ; int y = *( x + a ) ; // note that the use of sizeof() isn't required. For the pointer carries around // an implicit increment size (the size of the object to which it points). The above // is equivalent to // // int y = *(int*)((char*)x + (a*sizeof(*x)) ) ; }
此外,给定函数foo()
,编译器将(或应该)抱怨类型不匹配:
public void foo( int a[] ) { ... }
调用:
int *p = malloc(...) ; foo(p) ;
应该导致编译器抱怨类型不匹配。
第一个将arr
声明为驻留在堆栈上的int[100]
类型的数组 。 在某些情况下, arr
会衰减为int *
类型的指针,但这并不会使它成为指针。 为了进一步强调它不是指针, sizeof(arr)
将产生sizeof(int) * 100
,而不是地址的大小。
第二个声明一个int *
类型的指针 ,并将其初始化为malloc
返回的指针,实际上它在堆上分配内存。 请注意,在这种情况下, arr
不是数组 – 您可以使用数组表示法来偏移和取消引用指针,但这不会使它成为数组。
前者分配一个大小为100的自动数组,一旦超出范围,它将自动释放。
后者在free store中为100 int
s分配空间,并返回指向内存块开头的指针。 它将保持分配状态,直到指针调用free()
为止。
如果你只需要与当前范围一样长的内存,那么前者更容易使用(假设它不是太大。)否则,后一种选择是采取的方法。