簡體   English   中英

C語言,數組,指針

[英]C programming language, array, pointer

int main()
{
    int j=97;
    char arr[4]="Abc";
    printf(arr,j);
    getch();
    return 0;
}

此代碼給我一個堆棧溢出錯誤,為什么? 但是,如果我們使用printf(arr)而不是printf(arr,j) printf(arr)那么它將打印Abc。 請告訴我printf工作原理,這意味着第一個參數是const char*類型,因此編譯器如何處理arr。 抱歉! 上面的代碼是正確的,它沒有任何錯誤,我寫錯了。 但是下面的代碼給出了堆棧溢出錯誤。

#include <stdio.h>
int main()
    {
       int i, a[i];
       getch();
       return 0;
    }

由於變量我采用任何垃圾值,因此將是數組的大小,因此為什么當我使用DEV C ++時,如果我使用TURBO C ++ 3.0,此代碼為何會給出此錯誤,然后顯示error:constant expression required。 如果數組的大小不能可變,那么當我們通過用戶輸入獲取數組的大小時,不會顯示錯誤。 但是為什么在這種情況下。

請告訴我printf的工作原理

首先, 僅將非用戶提供或驗證的字符串傳遞給printf()的第一個參數!

printf()在必需的const char*參數之后接受可變數量的參數(因為printf()可變參數函數 )。 第一個const char*參數是您傳遞格式字符串的位置,以便printf()知道如何顯示其余參數。

如果arr字符數組包含用戶輸入的值,則如果字符串恰好包含那些格式占位符,則可能會導致段錯誤,因此格式字符串應始終為硬編碼的常量(或經過驗證的)字符串。 您的代碼示例很簡單,可以看到它確實是一個常數,但是習慣於使用printf("%s", arr)來顯示字符串而不是將它們直接傳遞給第一個參數(除非您絕對必須這樣做)仍然是一種好習慣。當然)。

就是說,您可以使用格式占位符(以%開頭的占位符)來格式化輸出。 如果要顯示:

abc 97

然后,您對printf()調用應為:

printf("%s %d", arr, j);

%s告訴printf()第二個參數應解釋為指向以空字符結尾的字符串的指針。 %d告訴printf()第三個參數應解釋為帶符號的十進制。

此代碼給我一個堆棧溢出錯誤,為什么?

請參閱AndreyT的答案。

我看到,現在OP將對行為的描述更改為完全不同的內容,因此我的解釋不再適用於他的代碼。 盡管如此,我關於可變參數功能的觀點仍然存在。

這段代碼導致堆棧無效(或類似的錯誤),因為您未能聲明函數printf printf是一個所謂的可變參數函數,它接受可變數量的參數。 在C語言中,幾乎總是必須在調用可變參數函數之前先聲明它們。 產生此要求的實際原因是可變參數函數可能(並且經常會)需要一些特殊的方法來傳遞參數。 它通常稱為調用約定 如果忘記在調用可變參數函數之前聲明它,則C99之前的編譯器將假定它是普通的非可變函數,並將其作為普通函數調用。 即它將使用錯誤的調用約定,從而導致堆棧無效。 這完全取決於實現方式:有些甚至看起來可以“正常工作”,有些甚至會崩潰。 但是無論如何,您絕對必須在調用可變參數函數之前先聲明它們。

在這種情況下,應在調用printf之前包括<stdio.h> 頭文件<stdio.h>是一個標准頭,其中包含printf的聲明。 你忘了做 因此錯誤(最有可能)。 由於它取決於實現,因此無法百分百確定。

否則,您的代碼有效。 該代碼很奇怪,因為您將j傳遞給printf而不為其提供格式說明符,但這不是一個錯誤printf只是忽略了多余的可變參數。 無論如何,您的代碼都應打印Abc 在代碼的開頭添加#include <stdio.h> ,假定它已完成您想要的工作,它應該可以正常工作。

同樣,此代碼

#include <stdio.h>

int main()
{
    int j=97;
    char arr[4]="Abc";
    printf(arr,j);
    return 0;
}

是一個奇怪的但完全有效的C程序,具有完美定義的輸出(盡管在輸出末尾添加\\n是個好主意)。

在您的int i, a[i];行中int i, a[i]; 在更正的破損代碼樣本中, ai元素的可變長度數組,但i未初始化。 因此,您的程序具有未定義的行為。

我懷疑printf()問題是一個紅色的鯡魚,因為以空終止的“ Abc”將忽略其他參數。

你調試過程序了嗎? 如果不能,您是否可以確定故障不在getch()中
我無法復制您的問題,但是為了簡單起見,我注釋掉了getch()

順便說一句,為什么不使用fgetc()getchar()呢? 您打算在更大的程序中使用curses嗎?

=====編輯后添加=====

好吧,不是紅鯡魚,只是OP的一個錯誤。

C ++確實允許分配一個由變量指定的大小的數組。 正如您所推論的那樣,您實際上已經使用隨機(垃圾)大小完成了此操作,並且使堆棧溢出。 使用C ++進行編譯時,通常不再編譯C,並且規則也會更改(取決於特定的編譯器)。

就是說,我不明白您的問題-您需要更加清楚“ 當我們通過用戶輸入獲取數組大小時 ……”

您會看到C語言的字符串被視為char*並且printf函數可以直接打印字符串。 要使用此功能打印字符串,應使用以下代碼:

printf("%s", arr);

%s告訴函數第一個變量將為char*

如果要同時打印arr和j,則應首先定義格式:

printf("%s%d", arr, j);

%d告訴函數第二個變量將是int

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM