我刚开始使用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
?
答案 0 :(得分:6)
我没有明确声明
int *a
作为指向数组的指针,但是如果我将它分配给某些内存,我可以使用a
,就像我已经声明它一样数组。声明带方括号的指针只是我在下面所做的快捷方式吗?
相似,但没有。 int *a
将a
声明为指向int
的指针。 int b[5]
为5 int
分配空间,将b
声明为常量指针数组{ - 1}}引用(在大多数情况下,它可以被视为指向int
int
的常量指针,并将int
定义为指向已分配空间的指针。因此,b
的效果超过int b[5]
,这也意味着int *a
比int *a
更灵活。例如,您可以增加int b[5]
,但不能增加a
。
b
在堆上分配内存。 malloc
,如果一个全局变量,将在程序的数据段中(即它逐字编译成可执行文件)。如果是本地的,它将在堆栈上分配。再次,类似但不同。
方括号实际上是在做一些指针运算吗?
在声明中,没有。当您使用指针变量时,是:int b[5]
与x[y]
相同。因此*(x + y)
与a[1]
相同,后者与*(a + 1)
相同(但请不要使用最后一个)。
为什么内存地址分配给
1[x]
而不是a
?
厚颜无耻的回答是因为你写了*a
而不是a = ...
。
*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*
,其余的只是指针算术,即第一个元素的地址a
,3 * sizeof(int)
已添加。
为什么将内存地址分配给a而不是* a?
我认为您在标识符和应用于变量的运算符之间会感到困惑。指针只是另一个变量;所有变量名称都应遵循标识符的规则,即标准:
标识符是一个任意长的字母和数字序列。
运算符*
取消引用它所应用的指针,并根据指针类型返回结果。因此,内存地址始终分配给变量a
。 a
指向的内存地址的值始终由*a
引用。
答案 4 :(得分:0)
为什么将内存地址分配给a而不是* a?
因为malloc()
会使用address
运算符返回您指定(存储在)指针vainrable a
中的=
。
通常我们会将address
返回的malloc()
存储在指针变量中,就像您完成语句a = malloc(5 * sizeof(int));
一样。
如果您尝试将malloc()
返回的地址存储在非指针变量中,那么您将遇到问题。