亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

C中的指針:何時使用&符號和星號?

C中的指針:何時使用&符號和星號?

C
慕絲7291255 2019-08-23 14:33:03
C中的指針:何時使用&符號和星號?我剛開始用指針,我有點困惑。我知道&一個變量的地址,它*可以在指針變量前面使用,以獲取指針指向的對象的值。但是當您使用數組,字符串或使用變量的指針副本調用函數時,情況會有所不同。在所有這些內部很難看到邏輯模式。什么時候應該使用&和*?
查看完整描述

3 回答

?
湖上湖

TA貢獻2003條經驗 獲得超2個贊

你有指針和價值觀:


int* p; // variable p is pointer to integer type

int i; // integer value

您將指針轉換為值*:


int i2 = *p; // integer i2 is assigned with integer value that pointer p is pointing to

您將值轉換為指針&:


int* p2 = &i; // pointer p2 will point to the address of integer i

編輯:在數組的情況下,它們被視為非常類似于指針。如果您將它們視為指針,您將使用它*來獲取它們內部的值,如上所述,但是使用[]運算符還有另一種更常見的方法:


int a[2];  // array of integers

int i = *a; // the value of the first element of a

int i2 = a[0]; // another way to get the first element

要獲得第二個元素:


int a[2]; // array

int i = *(a + 1); // the value of the second element

int i2 = a[1]; // the value of the second element

所以[]索引操作符是運算符的一種特殊形式*,它的工作原理如下:


a[i] == *(a + i);  // these two statements are the same thing


查看完整回答
反對 回復 2019-08-23
?
拉莫斯之舞

TA貢獻1820條經驗 獲得超10個贊

處理數組和函數時有一種模式; 起初有點難以看到。

在處理數組時,記住以下內容是有用的:當數組表達式出現在大多數上下文中時,表達式的類型被隱式地從“N元素數組T”轉換為“指向T”,并且其值被設置指向數組中的第一個元素。此規則的例外情況是,數組表達式顯示為&sizeof運算符的操作數,或者它是在聲明中用作初始值設定項的字符串文字。

因此,當您使用數組表達式作為參數調用函數時,該函數將接收指針,而不是數組:

int arr[10];...foo(arr);...void foo(int *arr) { ... }

這就是為什么你使用&運算符作為對應于“%s”的參數scanf()

char str[STRING_LENGTH];...scanf("%s", str);

由于隱式轉換,scanf()接收char *指向str數組開頭的值。這適用于使用數組表達式作為參數調用的任何函數(幾乎任何str*函數*scanf*printf函數等)。

在實踐中,您可能永遠不會使用&運算符調用帶有數組表達式的函數,如:

int arr[N];...foo(&arr);void foo(int (*p)[N]) {...}

這樣的代碼并不常見; 您必須知道函數聲明中數組的大小,并且該函數僅適用于指向特定大小的數組的指針(指向T的10元素數組的指針與指向11元素數組的指針的類型不同T)。

當數組表達式作為操作&符的操作數出現時,結果表達式的類型是“指向T的N元素數組的指針”,或者T (*)[N],它與指針數組(T *[N])和指向基類型的指針不同(T *)。

在處理函數和指針時,要記住的規則是:如果要更改參數的值并將其反映在調用代碼中,則必須將指針傳遞給要修改的事物。同樣,數組會投入一些動作,但我們會首先處理正常情況。

請記住,C 按值傳遞所有函數參數; 形式參數接收實際參數中值的副本,并且形式參數的任何更改都不會反映在實際參數中。常見的例子是交換功能:

void swap(int x, int y) { int tmp = x; x = y; y = tmp; }...int a = 1, b = 2;printf("before swap: a = %d, b = %d\n", a, b);swap(a, b);printf("after swap: a = %d, b = %d\n", a, b);

您將獲得以下輸出:

在交換之前:a = 1,b = 2交換后:a = 1,b = 2

形式參數xy從不同的對象ab,所以要改變xy未在反射ab。因為我們要修改的值ab,我們必須通過指針,以他們的交換功能:

void swap(int *x, int *y) {int tmp = *x; *x = *y; *y = tmp; }...int a = 1, b = 2;printf("before swap: a = %d, b = %d\n", a, b);swap(&a, &b);printf("after swap: a = %d, b = %d\n", a, b);

現在您的輸出將是

在交換之前:a = 1,b = 2交換后:a = 2,b = 1

請注意,在交換函數中,我們不會更改xand y的值,而是更改what xy 指向的值。寫作*x不同于寫作x; 我們沒有更新價值x本身,我們從該位置獲取位置x并更新該位置的值。

如果我們想要修改指針值,這同樣適用; 如果我們寫

int myFopen(FILE *stream) {stream = fopen("myfile.dat", "r"); }...FILE *in;myFopen(in);

然后我們修改輸入參數的值stream,而不是stream 指向stream的值,因此更改對值的影響沒有影響in; 為了使其工作,我們必須傳入一個指針指針:

int myFopen(FILE **stream) {*stream = fopen("myFile.dat", "r"); }...FILE *in;myFopen(&in);

再次,陣列投入了一些猴子扳手。將數組表達式傳遞給函數時,函數接收的是指針。由于如何定義數組下標,您可以在指針上使用下標運算符,就像在數組上使用它一樣:

int arr[N];init(arr, N);...void init(int *arr, int N) {size_t i; for (i = 0; i < N; i++) arr[i] = i*i;}

請注意,可能未分配數組對象; 即,你不能做類似的事情

int a[10], b[10];...a = b;

所以當你處理指向數組的指針時要小心; 就像是

void (int (*foo)[N]){
  ...
  *foo = ...;}

不行。


查看完整回答
反對 回復 2019-08-23
  • 3 回答
  • 0 關注
  • 790 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號