簡體   English   中英

scanf函數如何在C中工作?

[英]How does the scanf function work in C?

為什么在scanf函數中需要&符號(&)。 以下C代碼中的輸出或錯誤類型(編譯或運行時)是什么?

#include <stdio.h>

void main() {
    int a;
    printf("enter integer:");
    scanf("%d", a);
}

& in C是一個返回操作數地址的運算符。 可以這樣想,如果你只是給scanf變量a而沒有& ,它將被傳遞給它的值,這意味着scanf將無法設置它的值供你看。 通過引用傳遞它(使用&實際將指針傳遞給a )允許scanf設置它,以便調用函數也可以看到更改。

關於具體的錯誤,你無法真正說出來。 行為未定義。 有時,它可能會默默地繼續運行,而您不知道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

在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本身的引用。 更改barx沒有影響。

在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 int( unsigned * ),“%s”需要指向char的指針( char * ),“%f”需要指向float( 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需要一個或多個指針參數。 如果a是int變量,則它不是指針。 &a(“a的地址”)是一個指針,因此它將與scanf

這是因為在C中,函數參數是按值傳遞的 為了使scanf()函數來修改“ a在你的main()函數”變“的地址, a ”應當給予scanf()符號的,因此使用(地址)。

因為scanf需要一個指向該值將進入的變量(即引用)的指針。

您並不總是需要使用& with scanf 你需要做的是傳遞指針 如果你是C新手,你應該花點時間閱讀comp.lang.c FAQ:

http://c-faq.com/

特別:

scanf的'&'只需要獲取變量的地址。 可以通過使用指針使用scanf而不使用'&':

int myInt;
int * pointer_to_int;
pointer_to_int = &myInt;
scanf("%d", pointer_to_int);

通常,使用'&'通常比創建指針更容易,以避免使用'&'。

暫無
暫無

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

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