![](/img/trans.png)
[英]Why is my querySelectorAll not working even though I converted it to an array?
[英]Why is my code running even though I'm assigning 4 values on a 3 sized array?
順便說一句,我對編碼相當陌生:)
基本上我正在嘗試做一個程序,詢問學生他有多少個成績( div
),並計算總成績(nota=grade, im portuguese)。 請注意,在每次嘗試時,我總是輸入 '3' 和div
的值,而且我只顯示了部分代碼
至於 [CORRECT VERSION],在我看來一切正常並且運行良好。
**[CORRECT VERSION]**
short unsigned int div, i;
printf("Pretende fazer a media de quantas notas?(Máximo é 10): ");
scanf("%hd", &div);
float nota[div], media, soma = 0;
for(i = 0; i < div; i++) { //duvida linhas 25-26
pergunta:
printf("A %dª nota foi: ", i+1);
scanf("%f", ¬a[i]);
if((nota[i] < 0) || (nota[i] >20)) {
printf("\n(Erro: Por favor insira valores de 0 a 20\n");
goto pergunta;
我的疑問與for
循環中的 ["NON-SENSE" VERSION] for
。 我知道我在制作i++
,循環的第一次運行將假定i
為0 ,但在for
循環中, i
將為1 。 由於array_size=3,三年級(nota)將沒有要分配的槽位(因為nota[0] 將被跳過,這使得它為0 對嗎?只剩下2 個槽位),但循環仍然運行3次,要求 3 個等級並給我總體。
**["NON-SENSE VERSION]**
short unsigned int div, i;
printf("Pretende fazer a media de quantas notas?(Máximo é 10): ");
scanf("%hd", &div);
float nota[div], media, soma = 0;
for(i = 0; i++ < div;) { //duvida linhas 25-26
pergunta:
printf("A %dª nota foi: ", i);
scanf("%f", ¬a[i]);
if((nota[i] < 0) || (nota[i] >20)) {
printf("\n(Erro: Por favor insira valores de 0 a 20\n");
goto pergunta;
但是,將div
替換為3
,即使它與先前版本中假定的div
值相同,我也會遇到分段錯誤(以及其他一些實驗總線錯誤)
[VERSION WITHOUT div GIVING A NORMAL ERROR]
short unsigned int div, i;
//printf("Pretende fazer a media de quantas notas?(Máximo é 10): ");
//scanf("%hd", &div);
float nota[3], media, soma = 0;
for(i = 0; i++ < 3;) { //duvida linhas 25-26
pergunta:
printf("A %dª nota foi: ", i);
scanf("%f", ¬a[i]);
if((nota[i] < 0) || (nota[i] >20)) {
printf("\n(Erro: Por favor insira valores de 0 a 20\n");
goto pergunta;
你能解釋一下我遺漏了什么嗎,為什么即使是 ["NON-SENSE" VERSION] 也能運行,即使它和上一個幾乎一樣?
這里有很多東西要解壓,但讓我們按順序完成。
首先,不要這樣做:
unsigned div;
scanf("%hd", &div);
float nota[div], media, soma = 0;
如果您知道學生可以輸入的最大成績數量或使用動態分配,您應該預定義 MAX_SIZE。 可以在此 StackOverflow 問題中找到有關此的更多信息。 您正在做的是創建一個 VLA - 可變長度數組。 這是在 C99 標准中添加的,但使用它會降低可移植性,因為並非所有編譯器都遵守該標准。
其次,您使用的是非慣用的 for 循環。 編程中的一個習語是做某些事情的事實上的標准。 我們使用習語是因為它減少了出錯的機會,並使其他人更容易閱讀和維護我們的代碼。 這就是為什么我們堅持
for(int i = 0, i < n; i++){}
我想你知道這一點(正如你所說的無意義),但我只是把它放在那里給任何可能嘗試使用看起來像這樣的代碼for(i = 0; i++ < 3;)
- 這會給你留下你不想要的嚴重錯誤和行為。
將這兩者結合在一起,我們可以看到這里發生了什么:在您的無意義示例中,您使用的是 VLA。 它的工作方式取決於編譯器,但我猜在這種情況下編譯器會查看變量 div 的類型 - 因為它是一個無符號短整型,它知道該值在 (0 - 65,535 )*,所以值比較小。 因為它是一個很小的值,所以它在堆棧上分配了足夠的內存來容納一個最多約 65k 長的數組。 這意味着您可以“安全地”讀取和寫入該內存而不會出現堆棧溢出,因為操作系統已授予您的程序寫入內存中 65k 元素點的權限。
在另一種情況下,您對編譯器說您的數組將有 3 個元素長,因此您的程序僅從操作系統請求 3 個元素的空間。 然后操作系統不喜歡你試圖從它沒有給你的內存中讀寫,所以你最終會出現錯誤。
最后注意:請不要使用goto 。
*假設 unsigned short 是 16b long,這是最小值 - 它可以更長,具體取決於系統。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.