方括号如何在C中起作用?

时间:2015-04-14 01:27:10

标签: c arrays pointers malloc

我刚开始使用C而且我正在尝试理解基础知识。大量的教程会告诉你一些事情并让你相信它没有任何真正的解释,并且没有我能找到的人类可读的答案。

以下内容:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
  int *a;

  a = malloc(5 * sizeof(int));

  a[2] = 4;

  printf("%d\n", a[0]); // Prints 0
  printf("%d\n", a[2]); // Prints 4

  return 0;
} 

我没有明确声明int *a作为指向数组的指针,但是如果我将它分配给某些内存,我可以使用a,就像我已经声明它一样数组。声明带方括号的指针只是我在下面所做的快捷方式吗?方括号实际上是在做一些指针运算吗?

厚颜无耻的第二个问题

为什么内存地址分配给a而不是*a

5 个答案:

答案 0 :(得分:6)

  

我没有明确声明int *a作为指向数组的指针,但是如果我将它分配给某些内存,我可以使用a,就像我已经声明它一样数组。声明带方括号的指针只是我在下面所做的快捷方式吗?

相似,但没有。 int *aa声明为指向int的指针。 int b[5]为5 int分配空间,将b声明为常量指针int 数组{ - 1}}引用(在大多数情况下,它可以被视为指向int的常量指针,并将int定义为指向已分配空间的指针。因此,b的效果超过int b[5],这也意味着int *aint *a更灵活。例如,您可以增加int b[5],但不能增加a

b在堆上分配内存。 malloc,如果一个全局变量,将在程序的数据段中(即它逐字编译成可执行文件)。如果是本地的,它将在堆栈上分配。再次,类似但不同。

  

方括号实际上是在做一些指针运算吗?

在声明中,没有。当您使用指针变量时,是:int b[5]x[y]相同。因此*(x + y)a[1]相同,后者与*(a + 1)相同(但请不要使用最后一个)。

  

为什么内存地址分配给1[x]而不是a

厚颜无耻的回答是因为你写了*a而不是a = ...

编辑:John Bode提供了一个有用的指针(heh):常量指针和数组引用不是一回事,尽管它们非常相似。首先,*a = ...会给出不同的结果。

答案 1 :(得分:6)

  

方括号实际上是在做一些指针运算吗?

是。括号可以应用于任何指针,而不仅仅是数组。它们提供指针算术指针解除引用的简写。您的代码基本上是这样做的:

int *a = malloc(5 * sizeof(int));

*(a+2) = 4;

printf("%d\n", *(a+0));
printf("%d\n", *(a+2));

实际上这相当于:

int *a = malloc(5 * sizeof(int));

*((int*)(((unsigned long)a)+(2*sizeof(int)))) = 4;

printf("%d\n", *((int*)(((unsigned long)a)+(0*sizeof(int)))));
printf("%d\n", *((int*)(((unsigned long)a)+(2*sizeof(int)))));

答案 2 :(得分:5)

  

方括号实际上是在做一些指针运算吗?

a[b]相当于*(a + b)。所以是的,它是指针算术。它首先将指针偏移b,然后访问该内存位置,就像数组一样。

  

为什么内存地址分配给a而不是*a

内存地址存储在a中,因为a是指针,指针存储内存地址。 *a是该内存地址的数据。

答案 3 :(得分:2)

  

声明带方括号的指针只是我在下面所做的快捷方式吗?

当然不是!数组和指针是两个完全不同的东西。 int a[5];,此处a的类型为int[5],而int *b; b的类型为int*。在许多情况下,前者衰败成后者。这被称为arry decaying。阅读更多相关信息here

  

方括号实际上是在做一些指针运算吗?

是的,当你执行a[3]时真正发生的是*(a + 3),即a衰减到int*,其余的只是指针算术,即第一个元素的地址a3 * sizeof(int)已添加。

  

为什么将内存地址分配给a而不是* a?

我认为您在标识符和应用于变量的运算符之间会感到困惑。指针只是另一个变量;所有变量名称都应遵循标识符的规则,即标准:

  

标识符是一个任意长的字母和数字序列。

运算符*取消引用它所应用的指针,并根据指针类型返回结果。因此,内存地址始终分配给变量aa指向的内存地址的值始终由*a引用。

答案 4 :(得分:0)

为什么将内存地址分配给a而不是* a?

因为malloc()会使用address运算符返回您指定(存储在)指针vainrable a中的=

通常我们会将address返回的malloc()存储在指针变量中,就像您完成语句a = malloc(5 * sizeof(int));一样。

如果您尝试将malloc()返回的地址存储在非指针变量中,那么您将遇到问题。