[英]Why is it that we declare 2d arrays with 1 based indexing but we access the array with 0 based indexing in C language?
`int main()
{
int nums[3][2] = {{1, 2}, {3, 4}, {5, 6}};
printf("%d", nums[2][1]);
return 0;
}`
在這里,如果我想訪問數組的最后一個元素,我會使用 [2][1] 但要命名數組,我會使用基於 1 的索引並使用 [3][2]。 有人可以解釋為什么嗎?
您將length與index混淆了。 對於長度為N的數組,索引是0到N-1 。
那是:
int x[3];
表示x[0]
、 x[1]
和x[2]
存在。 有 3 個條目,編號為 0.. 2。
長度只是“基於 1”的,因為當我們談論長度為 1 的數組時,我們通常是指它可以容納一個條目,因為這就是人類傾向於計數的方式。 然而,索引是從 start 開始的偏移量,因為它實際上是 C 在內部如何工作的產物:
x[n] // Array notation
*(x + n) // Pointer notation
當您說x[0]
時,您是在說“在數組的開頭應用零偏移並讀取值”,即使生成的機器指令看起來更多,也可以翻譯成人類術語“讀取第一個元素”像第一個解釋。
實現基於 1 的 arrays 的其他語言實際上必須減去該偏移量才能讀取正確的 memory 位置。 換句話說,他們是在偽造它。
當您“命名”數組時(正確的術語是“聲明/定義”),數字代表大小,或更准確地說是數組中元素的數量。
當你訪問一個元素時,你使用數組中元素的索引,這基本上是“元素數量,它離數組的開頭有多遠”。
所以第一個元素的索引為 0。
數組聲明括號中的數字是元素的數量,而不是最后一個元素的索引。 但這與 C 聲明如何工作的既定哲學有一個有趣的偏差。
Kernighan 和 Ritchie 在The C Programming Language , 1978, page 90 中描述了聲明符如何提供一種正在使用的標識符的圖片:
指針
px
的聲明是新的。
int *px;
旨在作為助記符; 它說
*px
的組合是一個int
,也就是說,如果px
出現在上下文*px
中,它相當於一個int
類型的變量。 實際上,變量聲明的語法模仿了變量可能出現的表達式的語法。 這種推理在涉及復雜聲明的所有情況下都很有用。 例如,
double atof(), *dp;
表示在表達式中
atof()
和*dp
具有double
類型的值。
因此,我們看到,在諸如int *p
之類的聲明中, *p
為我們提供了將使用p
的表達式的“圖片”。標識符的實際類型來自圖片:因為*p
是一個int
,那么p
是一個指向int
的指針。
如果我們忠實於這個 model,那么int x[2]
會告訴我們x[2]
是一個int
,所以x
必須是一個int
數組並且它必須有一個索引為 2 的成員,所以它必須是一個數組至少 3 int
。 相反,它決定聲明器將包含元素的數量而不是最大索引。
這在很大程度上是一個武斷的決定——編譯器可以設計為以任何一種方式工作。 我沒有看到 Kernighan 和 Ritchie 在C Programming Language的任何一個版本中討論這個選擇。 他們將數字稱為數組大小的“界限”,但沒有說明為什么他們偏離“圖片”方案以使用多個元素而不是樣本索引。 (奇怪的是,我什至沒有看到數字是元素數量的聲明。我看到了表明它的示例,但沒有明確的聲明。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.