C中指针和数组的区别

时间:2014-08-13 14:44:20

标签: c arrays pointers

我只是对这些代码感到困惑。

int state[arraySize] = {};

int *state;
state = (int*)calloc(arraySize,sizeof(int));
//............
free(state);

它们之间的区别是什么? 因为我需要为我的程序收集一些数字。并且每次使用可能影响数组大小的不同变量运行。所以我不能立即使用数组。但当我将数组更改为(2)时,我的代码结果显示不同,有时似乎进入了一个死循环。

5 个答案:

答案 0 :(得分:2)

指针指向另一个内存区域。在第二个示例中,state不是数组,指向数组。即通过跟随(或解除引用)指针找到一个数组。

另一方面,数组是一个足够大的内存区域,可容纳某些类型的元素。在您的第一个示例中,state是一个可能包含arraySize int s的内存区域。

令人困惑的是,在许多情况下,您可以命名一个数组,并且将指向指向数组第一个元素的指针。这是array-to-pointer decay

答案 1 :(得分:2)

C-FAQ 6.2

  

数组声明char a[6]请求空格容纳六个字符,以名称a知道。也就是说,有一个名为a的位置,可以坐6个字符。另一方面,指针声明char *p 请求一个包含指针的地方,名称为p。这个指针几乎可以指向任何地方:任何char,或char的任何连续数组,或无处。   像往常一样,一张图片胜过千言万语。声明

char a[] = "hello";
char *p = "world";
     

会初始化数据结构,可以这样表示:

enter image description here

如果是

int *state = calloc(arraySize,sizeof(int));  

在堆上分配了一块内存。 state现在指向该块的第一个内存单元。可以使用指针算法访问存储器单元的其余部分。如果state指向内存地址0x100,那么state + 1将指向0x104(占用4个字节的int)。

state       -----> Points to the first memory cell of the allocated memory block.
state + 1   -----> Points to the second memory cell of the allocated memory block.
state + 2   -----> Points to the third memory cell of the allocated memory block.  
...
...

您应该注意:指针算术数组索引在C中等效指针与数组不同

答案 2 :(得分:1)

这看起来更像是C而不是C ++。不同之处是:

  1. 第一个在其生命周期中具有“固定”大小。 C99允许arraySize是一个变量,但它在调用堆栈中仍然是“自动的”。

  2. 第二个是指针,calloc的调用将其指向一些已分配的内存,这些内存将保留在存储中,直到调用free为止。该功能返回后可以进行免费。

  3. 第一个state是一个r值。您无法指定state指向其他位置。您无法安全地从功能中返回它。

    如果您同时使用sizeof(state),您还会看到第一个将是sizeof(int)*arraySize,第二个将是指针的标准大小。如果arraySize为50sizeof(int)为4且sizeof(int *)为8,则第一个将为200,第二个为8。

答案 3 :(得分:1)

如前所述,指针只是一个可以被引用的内存区域,它保存内存中另一个位置的地址(或者更精确的“堆”),其中包含实际数据。另一方面,数组是聚合数据类型,这意味着它包含通常在连续的存储区域中的元素集合(相同数据类型的单个小孔)。数组的第一个元素是指向结构开头的指针。让我们把所有这些都放到一些代码中。

<强>指针

有多种方法可以使用指针,具体取决于您希望它们的灵活程度。最简单的方法是让指针指向一个变量,比如

int a = 1;
int* a_ptr = &a;

int b = *a_ptr;  /* b is initialized to 1 via the pointer to a. */

<强>阵列

另一方面,数组也是一个非常简单的概念。请记住,数组中第一个元素的地址是整个结构的说明地址。

当我们访问数组时,我们使用传统的表示法:

int someArr[3] = {0, 2, 4};

someArr[0]; /* 0 */
someArr[1]; /* 2 */
someArr[2]; /* 4 */

但我们也可以使用常规指针解除引用语法来访问数组:

*(someArr); /* 0 */
*(someArr + 1); /* 2 */
*(someArr + 2); /* 4 */

清楚地揭示了与指针有多密切关系的数组。作为代码最后一部分的解释:

*(someArr + n)其中'n'是在内存中提前检索指向的值的数组类型的字节数,所以:

*(someArr + n)与*(someArr +(n * [数组元素类型的大小]))相同,以查找数组元素'n'的值。

答案 4 :(得分:0)

第一个数组完全由范围控制。它将正确分配所需的内存,当变量退出escope时,内存将自动自动。

第二个你必须自己控制记忆。它没有一个已定义的范围,但如果你在它无法触及时不销毁它,它将留下内存泄漏。

为了帮助您更多地了解死循环,我需要更多关于您使用数组或数组指针做什么的信息。