[英]Array Initialization
我試圖在for循環的條件內分配數組內的值:
#include <iostream>
using namespace std;
int* c;
int n;
int main()
{
scanf("%d", &n);
c = new int[n];
for (int i = 0; i < n; c[i] = i++ )
{
printf("%d \n", c[i]);
}
return 0;
}
但是,我沒有獲得所需的輸出,因為n = 0 1 2 3 4
。 相反,如果我使用指令, c[i] = ++i
,我將獲得輸出-842150451 1 2 3 4
。 能否請您解釋一下我們的代碼是否像這樣,我該如何糾正?
表達式++i
的值是i
遞增后的值。 因此,如果它從0開始,則第一次分配值1,依此類推。 您可以看到價值得到了分配,但問為什么它得到分配有打開一罐蠕蟲。
在i
中通過i++
或 ++i
修改i
的表達式中使用i
是未定義的行為,除非在兩者之間存在所謂的“序列點”。 在這種情況下,沒有。 請參閱該語言相當復雜的部分的未定義行為和序列點 。
盡管標准未對行為進行定義,但從一次運行到另一次運行可能不一致,顯然您的程序已經完成了某些操作 。 顯然它根本沒有分配給索引0(至少,不是在第一次打印之前,考慮到循環體在“for”的最后一部分之前發生,這是可以理解的)所以你得到的任何事情都恰好是在分配給你的原始內存中。 它為索引1
分配1
,依此類推。
這意味着它也可能試圖將值5
分配給c[5]
,這是一類被稱為“緩沖區溢出”的錯誤,並且在您已經獲得的內容之上有更多未定義的行為。 嘗試分配它可能會覆蓋其他內存,在任何一天可能包含或不包含重要內容。
修復是為c[0]
分配一些值,並且不要嘗試分配給c[5]
,它仍然不存在,並且不要嘗試無效地使用i
“同時”遞增它。 通常你會寫這個:
for (int i = 0; i < n; ++i) {
c[i] = i;
printf("%d \n", c[i];
}
如果你因為某種原因迫切需要在for循環的第三個子句中進行賦值,你可以使用逗號運算符來引入一個序列點:
for (int i = 0; i < n; c[i] = i, ++i) {
}
但是當然如果你這樣做那么你就不能在循環體中打印c[i]
的值。 它尚未分配,因為直到每個循環結束才會評估第三個子句。
您也可以嘗試c[i] = i+1, ++i
,但不能嘗試++i, c[i] = i
因為我們會在最后一次迭代時回到嘗試分配給c[5]
。
首先,你需要了解for循環的最后一部分是在每次迭代結束時執行的,所以你看到這個原因:
-842150451 1 2 3 4
是因為你在分配之前打印c[0]
,所以值可以是任何值。 其余部分符合預期。
課; 不要偷偷摸摸地將東西塞進for循環的最后一部分。 使您的代碼清晰簡單:
for (int i = 0; i < n; ++i )
{
c[i] = i;
printf("%d \n", c[i]);
}
首先,您聲稱要在“循環條件”內分配值。 在for
循環中,條件是標題的第二部分(在您的情況下為i < n
)。 您正在第三部分執行分配,這不是條件。 那么,為什么你說你想在條件中分配值,但卻沒有這樣做?
其次,像c[i] = i++
或c[i] = ++i
這樣的表達式在C ++語言中沒有任何已定義的行為。 在C ++中,修改變量是非法的,同時在沒有插入序列點的情況下將其讀取用於任何其他目的。 然而,你正是這樣做的。 對代碼的行為沒有任何有意義的解釋。 代碼的行為未定義 。 它可以為任何隨機原因做任何事情。
第三,初始化for
條件中的任何內容通常都不是一個好主意。 你能更詳細地解釋一下你想做什么以及為什么? 沒有它,很難想出任何有意義的東西。
c[i] = ++i
之所以產生未定義的行為。 它既未定義為++
值(前置或后置),又在同一表達式中再次使用它。 在這種情況下,似乎++i
正在被評估之前,並導致執行基本上是
c[1] = 1;
c[2] = 2;
...
這意味着c[0]
永遠不會被初始化,而是基本上具有垃圾值。 看起來你想要的順序是
c[0] = 0;
c[1] = 1;
要獲得此排序,您需要將初始化和增量分成單獨的語句。
c[i] = i;
i++;
您的基本問題是for(;;)結構中的語句如何被分解和執行。 for(st1; st2; st3)結構旨在與以下內容相同:
st1;
while (st2) {
<body>
st3;
}
因此,您的第三個語句c[i] = i++
將在 printf
語句之后執行,並且您正在打印未初始化的數據。
預增量與后增量問題模糊了這一點。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.