[英]array passed as array and pointer-C
為什么該程序產生p
和q
作為輸出? 將數組作為指針或數組傳遞有什么區別?
#include<stdio.h>
void fun(char i[]){
printf("%c,%c", i[1],i[2]);
}
void fun2(char *i){
printf("\n%c,%c", i,i+1);
}
int main(){
char ar[] = {"Aba"};
fun(ar);
fun2(ar);
return 0;
}
輸出:
b,a
p,q
您正在第二個函數中打印指針地址的ASCII轉換。 您必須通過*i
和*(i+1)
解引用指針。
將數組作為指針或數組傳遞有什么區別?
fun
和fun2
這兩個函數的簽名是等效的。 因此,您實際上並不像您想的那樣在fun()
有一個數組。 這是因為在C語言中,當您將數組傳遞給函數時,它將轉換為指向其第一個元素的指針。
所以,這條語句在fun2()
printf("\n%c,%c", i,i+1);
不打印字符,但地址i
和i+1
。 這也不對,因為它們與您指定的格式不匹配。
當我使用gcc編譯您的代碼時,它會發出警告:
In function ‘fun2’:
warning: format ‘%c’ expects argument of type ‘int’, but argument 2 has type ‘char *’ [-Wformat=]
printf("\n%c,%c", i,i+1);
^
warning: format ‘%c’ expects argument of type ‘int’, but argument 3 has type ‘char *’ [-Wformat=]
如您所見,格式說明符和傳遞的參數不匹配。 要打印i
和i+1
指向的值,可以像在fun()
那樣打印它:
int fun2(char *i){
printf("\n%c,%c", i[1],i[2]);
}
要打印值,您應該在兩個函數中都使用*i
和*(i+1)
或i[0]
和i[1]
。 i
包含您傳遞的數組的第一個地址單元。 在任何一種情況下,兩者都通過其地址。
希望我的長答案對您有所幫助!
我采用整數,該概念對於任何數據類型均相同:char,floats等,等等。
好吧,關於數組和指針的簡短課程。
經驗法則1:數組和指針幾乎總是可以互換的,但是也有例外!
以一維數組為例,我們可以這樣聲明:-
int arr[10];
這將聲明一個名為arr
的變量,該變量可以容納10個整數元素。
我可以類似地使用指針表示法通過指針變量或通過使用數組名( arr
)本身來表示此數組。
printf ("%d", arr[2]); // Array method : will print out the third element, indexing starts from 0
經驗法則2:數組名稱(無論是1D 2D 3D 4D)總是衰減為指針或地址。
printf ("%lu", arr) //will print out the base address of the array, i.e address of the first element
如何使用指針打印值? 只需使用*
運算符取消引用即可。
printf("%d", *arr) //Pointer notation - will print the first value
如何使用另一個變量引用數組?
int *ptr = arr; //Pointer notation - just simply write the array name as it decays into an address
printf("%d", *ptr); //Pointer notation - prints the first element
許多人說int * ptr是指向數組的指針。
實際上不是。 實際上,它是指向整數而不是數組的指針。 為什么?
因為首先要存儲數組的第一個整數的地址,然后可以通過增加指針來遍歷它。 因此,在實際指針中存儲的是整數(第一個整數)的地址。
現在,進入二維數組:
宣言:-
int arr[2][3]; // arrays of 2 rows and 3 columns, total 6 elements
相同的規則暗示:
printf("%d", arr[0][1]); //prints the second element of the first row.
printf("%lu", arr) //prints the base address of the 2D array
指向指針符號:-
printf("%d", *(*(arr + 0) + 1); // how this works?
arr包含地址。 向其添加整數使您跳至該行。
arr + 1 // gives the second row, i.e. arr is currently pointing to the first element of second row.
現在,進一步向其添加一個整數,將使您跳至該特定行中的指定列。
((arr + 1) // second row + 2 ) // will you skip to third element of the second row
當您選擇將數組名稱視為指針時,這是語言為您提供的隱式指針符號。
現在遇到您的問題:-顯式指針符號:-
您要實現的目標是將2D數組的基地址存儲在指針中。
如何正確做到這一點?
int (*ptr)[3]; //reading it goes like this - ptr is a pointer to a 1D array of 3 ints
此處的3指定2D數組具有的列數。
因此,它正在嘗試將2D數組的第一個 1D數組的基地址(即第0行基地址)存儲到指針中。
其余的保持不變。
int (*ptr)[3] = arr; // storing the 2D array in ptr
現在,您可以將其用作普通指針(指針符號適用於它)
(ptr + 1) //now ptr is pointer to the Second 1D array of that 2D array or you can say to the second row's first element.
您可以在函數中捕獲數組的另一種方式是這樣的:
我很少使用它。
int main()
{
int arr[2][2];
fun(arr);
}
void fun(int catch[][])
{
}
// This is simple to understand and as well as to relate. Now, again catch can be used as pointer or as an array. It depends on you :)
void fun1(int (*ptr)[2])
{
//my way
printf("%d", ptr[1][1]);
printf("%d", *(*(ptr + 1) + 1));
//answer will be the same
}
//Ptr now contains that 2D array base address, again can be used as an array or a pointer :)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.