1)指针不是数组。数组不是指针。不要那样想它们,因为它们是不同的。
我怎样才能证明这一点?想想它们在记忆中的样子:
我们的数组arr
有 10 个字符长。它包含“你好”,但等等,这还不是全部!因为我们有一个静态声明的数组比我们的消息长,所以我们得到一堆 NULL 字符 ( '\0'
) 免费抛出!另外,请注意名称arr
在概念上是如何附加到连续字符的(它不指向任何东西)。
接下来考虑我们的指针在内存中的样子:
注意这里我们指向只读内存中某个位置的字符数组。
因此,虽然两者arr
和ptr
都以相同的方式初始化,但每个的内容/位置实际上是不同的。
这是关键点:
ptr是一个变量,我们可以将它指向任何东西,arr是一个常量,它总是会引用这个 10 个字符的块。
2) The[]
是可用于地址的“添加和引用”运算符。意思arr[0]
和说的一样*(arr+0)
。所以是的,这样做:
printf("%c %c", *(arr+1), *(ptr+1));
会给你一个“e e”的输出。这不是因为数组是指针,而是因为数组的名称arr
和指针ptr
都恰好给了你一个地址。
#2 的关键点:引用运算符*
和加法和引用运算符[]
并不分别特定于指针和数组。这些运算符只处理地址。
3)我没有一个非常简单的答案......所以让我们暂时忘记我们的字符数组,看看这个例子来解释一下:
int b; //this is integer type
&b; //this is the address of the int b, right?
int c[]; //this is the array of ints
&c; //this would be the address of the array, right?
所以这是可以理解的:
*c; //that's the first element in the array
那行代码告诉你什么?如果我尊重c
,那么我会得到一个 int。这意味着只是一个简单c
的地址。由于它是数组的开头,它是数组的地址,也是数组中第一个元素的地址,因此从值的角度来看:
c == &c;
4) 让我暂时离开话题……最后一个问题是地址算术混乱的一部分。我曾经看到一个关于 SO 的问题,暗示地址只是整数值......您需要了解在 C 中地址具有类型知识。也就是说:
iarr+1; //We added 1 to the address, so we moved 4 bytes
arr+1; //we added 1 to the address, so we moved 1 byte
基本上sizeof(int)
是 4 而sizeof(char)
是 1。所以“将 1 添加到数组”并不像看起来那么简单。
那么现在,回到问题,为什么与arr+1
不同&arr+1
?第一个是向1 * sizeof(char)
地址添加 =1,第二个是向1 * sizeof(arr)
地址添加 =10。
这就是为什么即使它们都“只加 1”,它们也会给出不同的结果。