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

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
形式參數x
和y
從不同的對象a
和b
,所以要改變x
和y
未在反射a
和b
。因為我們要修改的值a
和b
,我們必須通過指針,以他們的交換功能:
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
請注意,在交換函數中,我們不會更改x
and y
的值,而是更改what x
和y
指向的值。寫作*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 = ...;}
不行。
- 3 回答
- 0 關注
- 790 瀏覽
添加回答
舉報