[英]How do square brackets work in C?
我剛剛開始使用 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
的內存地址?
我還沒有明確宣布
int *a
作為指向數組的指針,但如果我將它分配一些內存,然后我就可以用a
像我宣布它作為一個陣列。 用方括號聲明指針只是我在下面所做的工作的快捷方式嗎?
類似,但沒有。 int *a
聲明a
作為指針int
。 int b[5]
分配為5空間int
S,聲明b
為
常數指針
的陣列OF- 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 + a)
相同,后者又與1[a]
相同(但請不要使用最后一個)。
為什么分配給
a
而不是*a
的內存地址?
一個厚顏無恥的問題的厚臉皮答案:因為你寫a = ...
而不是*a = ...
。
編輯:John Bode 給出了一個有用的指針(heh):常量指針和數組引用不是一回事,盡管它們非常相似。 一方面, sizeof(...)
會給出不同的結果。
方括號實際上是在做一些指針運算嗎?
是的。 括號可以應用於任何指針,而不僅僅是數組。 它們提供了指針算術和指針解引用的簡寫。 您的代碼基本上是這樣做的:
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)))));
方括號實際上是在做一些指針運算嗎?
a[b]
等價於*(a + b)
。 所以是的,它是指針算術。 它首先將指針偏移b
,然后訪問該內存位置,就像數組一樣。
為什么分配給
a
而不是*a
的內存地址?
內存地址存儲在a
因為a
是指針,而指針存儲內存地址。 *a
是該內存地址處的數據。
用方括號聲明指針只是我在下面所做的工作的快捷方式嗎?
當然不是! 數組和指針是兩個完全不同的東西。 int a[5];
, 這里a
是int[5]
類型,而在int *b;
b
的類型是int*
。 在許多情況下,前者會衰變成后者。 這被稱為 arry 衰減。 在此處閱讀更多相關信息。
方括號實際上是在做一些指針運算嗎?
是的,當你做a[3]
,真正發生的是*(a + 3)
即a
衰減為int*
,其余的只是指針算術,即指向a
的第一個元素的地址, 3 * sizeof(int)
是添加。
為什么分配給a而不是*a的內存地址?
我認為您在標識符和應用於變量的運算符之間感到困惑。 指針只是另一個變量; 所有變量名稱都應遵循標識符規則,即來自標准:
標識符是任意長的字母和數字序列。
而運算符*
取消引用它所應用的指針並根據指針類型返回結果。 所以內存地址總是分配給a
,變量。 a
指向的內存地址處的值總是由*a
引用。
為什么分配給a而不是*a的內存地址?
因為malloc()
返回一個address
要為其分配給指針vairable(在存儲) a
使用=
運算符。
通常我們將malloc()
返回的這些address
存儲在一個指針變量中,就像您對語句a = malloc(5 * sizeof(int));
所做的那樣a = malloc(5 * sizeof(int));
.
如果您嘗試將malloc()
返回的地址存儲在非指針變量中,那么您將遇到問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.