這個問題在這里已經有了答案: C 從陣列定義行為中間的指標進行負索引? (1 個回答) 為什么 C 允許使用負索引和大于陣列長度減 1 的索引進行索引?[重復] (2個答案) 1 小時前關閉。
C 陣列允許負索引,但我想不出它的用途,因為你永遠不會有一個負索引的元素。
當然,你可以這樣做:
struct Foo {
int arr1[3] = { 1, 2, 3 };
int arr2[3] = { 4, 5, 6 };
};
int main() {
Foo foo;
std::cout << foo.arr2[-2] << std::endl; //output is 2
}
但是為什么你會想做這樣的事情呢?無論如何,何時需要對陣列進行負索引,以及您將在哪些域中進行?
uj5u.com熱心網友回復:
請記住,當您對陣列進行索引時,您會獲得 indexN處的元素,即&array[0] sizeof(array[0]) * N.
假設您有以下代碼:
#include <stdio.h>
int main()
{
int a[5] = {5, 2, 7, 4, 3};
int* b = &a[2];
printf("%d", b[-1]); // prints 2
}
uj5u.com熱心網友回復:
C 陣列允許負索引
并不真地。陣列索引歸結為使用加法( 和 -)運算子的指標算術。從 C17 6.5.6/8 強調我的:
如果指標運算元指向陣列物件的元素,并且陣列足夠大,則結果指向與原始元素偏移的元素,使得結果和原始陣列元素的下標之差等于整數運算式。...
如果指標運算元和結果都指向同一個陣列物件的元素,或者超過陣列物件的最后一個元素,則評估不應產生溢位;否則,行為是 undefined。
首先允許的原因-是因為它對于基于某個索引計算相對偏移量很有用。但是偏移量仍然必須最終指向陣列中的一個專案,或者您呼叫未定義的行為。
您的 struct example 實際上就是這樣做的——不能保證這兩個陣列是相鄰分配的(即使很有可能)。編譯器可以自由地在兩個陣列之間插入填充。此外,編譯器可以自由假設arr1我們永遠不會修改它以防萬一foo.arr2[-2]=3;。
此代碼理論上可以列印 2 2 2:
std::cout << foo.arr2[-2] << std::endl;
std::cout << foo.arr1[1] << std::endl; // store foo.arr1[1] in a register
foo.arr2[-2]=3;
std::cout << foo.arr1[1] << std::endl; // print once more using that same register
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/527278.html
標籤:C 数组C指针
