爲什麼在scanf
函數中需要使用&符號(&)。以下C代碼中的輸出或錯誤類型(編譯或運行時)是什麼?scanf函數在C中如何工作?
#include <stdio.h>
void main() {
int a;
printf("enter integer:");
scanf("%d", a);
}
爲什麼在scanf
函數中需要使用&符號(&)。以下C代碼中的輸出或錯誤類型(編譯或運行時)是什麼?scanf函數在C中如何工作?
#include <stdio.h>
void main() {
int a;
printf("enter integer:");
scanf("%d", a);
}
C中的&
是一個返回操作數地址的運算符。想一想,如果你只是給scanf
變量a
沒有&
,它會通過值傳遞給它,這意味着scanf
將無法爲您設置其值。通過引用(使用&
實際上傳遞指向a
的指針)允許scanf
進行設置,以便調用函數也可以看到更改。
關於具體的錯誤,你真的不知道。行爲是未定義的。有時,它可能會默默繼續運行,而您不知道在您的程序中某處改變了某些值。有時,它會導致程序在這種情況下立即崩潰,如:
#include <stdio.h>
int main()
{
int a;
printf("enter integer: ");
scanf("%d",a);
printf("entered integer: %d\n", a);
return 0;
}
編譯它顯示了這一點:
$ gcc -o test test.c
test.c: In function ‘main’:
test.c:6: warning: format ‘%d’ expects type ‘int *’, but argument 2 has type ‘int’
和執行節目分段錯誤:
$ ./test
enter integer: 2
Segmentation fault
因爲scanf
需要一個指向該值將會進入的變量(即引用)的指針。
如果您「我問這樣的問題,我會建議現在就學習,」它只是做「。
您將瞭解到您需要使用&符號,因爲scanf
需要一個或多個指針參數。如果a是一個int變量,它不是一個指針。 & a(「a的地址」)是一個指針,所以它將與scanf
一起使用。
這是因爲在C中,函數參數是,通過值傳遞。爲了使scanf()
函數修改main()函數中的'a
'變量,'a
'的地址應賦予scanf()
,因此使用「與」號(地址)。
你不總是需要使用&
與scanf
。你需要做的是通過指針。如果你是新來的C,你應該花一些時間閱讀comp.lang.c常見問題解答:
具體做法是:
在C中,所有的函數參數都是按值傳遞的;對函數形式參數的任何更改都不會反映在實際參數中。例如:
void foo(int bar)
{
bar = bar + 1;
}
int main(void)
{
int x = 0;
printf("x before foo = %d\n", x);
foo(x);
printf("x after foo = %d\n", x);
return 0;
}
該方案的輸出將是
x before foo = 0 x after foo = 0
因爲bar
接收的x
(0),而不是一個參考值來x
本身。更改bar
對x
沒有影響。
在C中,解決這個問題的方法是將一個指針傳遞給一個變量:
void foo(int *bar)
{
*bar = *bar + 1;
}
int main(void)
{
int x = 0;
printf("x before foo = %d\n", x);
foo(&x);
printf("x after foo = %d\n", x);
return 0;
}
現在程序的輸出是
x before foo = 0 x after foo = 1
這一次,形參bar
不是int,而是一個指針爲int,並且它接收地址的x
(由給定的在調用foo
時表達式&x
),而不是x中包含的值。表達*bar
的意思是「在位置欄得到的值指向」,所以*bar = *bar + 1
對應於x = x + 1
。
由於scanf()
需要寫入它的參數,它預計這些參數類型爲指針。的「%d」轉換指定期望對應的參數是一個指針到int(int *
)中,「%u」的轉換說明需要一個指向無符號整型(unsigned *
),「%S」期望字符指針(char *
) 「%F」需要一個指向浮動(float *
)等。在你的榜樣,因爲a
鍵入int
,您需要使用表達式&a
獲取一個指針。
注意,如果a
已經指針類型,你就不會需要使用&
運營商在呼叫scanf()
:
int main(void)
{
int a, *pa; // declare pa as a pointer to int
...
pa = &a; // assign address of a to pa
scanf("%d", pa); // scanf() will write to a through pa
...
}
還要注意的是傳遞一個數組時的功能(例如,當使用「%s」轉換說明符來讀取字符串),則不需要使用&
運算符;陣列表達將隱式轉換爲指針類型:
int main(void)
{
char name[20];
...
scanf("%19s", name); // name implicitly converted from "char [20]" to "char *"
...
}
在scanf
的「&」只需要得到一個變量的地址。您可以通過使用指針使用scanf
無「&」:
int myInt;
int * pointer_to_int;
pointer_to_int = &myInt;
scanf("%d", pointer_to_int);
一般情況下,使用「&」往往比創建的指針,以避免使用「&」更容易。
順便說一句,'main'返回'int',不'void'。 – 2010-01-14 15:31:10