3 回答

TA貢獻(xiàn)2003條經(jīng)驗(yàn) 獲得超2個(gè)贊
你有指針和價(jià)值觀(guān):
int* p; // variable p is pointer to integer type
int i; // integer value
您將指針轉(zhuǎn)換為值*:
int i2 = *p; // integer i2 is assigned with integer value that pointer p is pointing to
您將值轉(zhuǎn)換為指針&:
int* p2 = &i; // pointer p2 will point to the address of integer i
編輯:在數(shù)組的情況下,它們被視為非常類(lèi)似于指針。如果您將它們視為指針,您將使用它*來(lái)獲取它們內(nèi)部的值,如上所述,但是使用[]運(yùn)算符還有另一種更常見(jiàn)的方法:
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
要獲得第二個(gè)元素:
int a[2]; // array
int i = *(a + 1); // the value of the second element
int i2 = a[1]; // the value of the second element
所以[]索引操作符是運(yùn)算符的一種特殊形式*,它的工作原理如下:
a[i] == *(a + i); // these two statements are the same thing

TA貢獻(xiàn)1820條經(jīng)驗(yàn) 獲得超10個(gè)贊
處理數(shù)組和函數(shù)時(shí)有一種模式; 起初有點(diǎn)難以看到。
在處理數(shù)組時(shí),記住以下內(nèi)容是有用的:當(dāng)數(shù)組表達(dá)式出現(xiàn)在大多數(shù)上下文中時(shí),表達(dá)式的類(lèi)型被隱式地從“N元素?cái)?shù)組T”轉(zhuǎn)換為“指向T”,并且其值被設(shè)置指向數(shù)組中的第一個(gè)元素。此規(guī)則的例外情況是,數(shù)組表達(dá)式顯示為&
或sizeof
運(yùn)算符的操作數(shù),或者它是在聲明中用作初始值設(shè)定項(xiàng)的字符串文字。
因此,當(dāng)您使用數(shù)組表達(dá)式作為參數(shù)調(diào)用函數(shù)時(shí),該函數(shù)將接收指針,而不是數(shù)組:
int arr[10];...foo(arr);...void foo(int *arr) { ... }
這就是為什么你不使用&
運(yùn)算符作為對(duì)應(yīng)于“%s”的參數(shù)scanf()
:
char str[STRING_LENGTH];...scanf("%s", str);
由于隱式轉(zhuǎn)換,scanf()
接收char *
指向str
數(shù)組開(kāi)頭的值。這適用于使用數(shù)組表達(dá)式作為參數(shù)調(diào)用的任何函數(shù)(幾乎任何str*
函數(shù)*scanf
和*printf
函數(shù)等)。
在實(shí)踐中,您可能永遠(yuǎn)不會(huì)使用&
運(yùn)算符調(diào)用帶有數(shù)組表達(dá)式的函數(shù),如:
int arr[N];...foo(&arr);void foo(int (*p)[N]) {...}
這樣的代碼并不常見(jiàn); 您必須知道函數(shù)聲明中數(shù)組的大小,并且該函數(shù)僅適用于指向特定大小的數(shù)組的指針(指向T的10元素?cái)?shù)組的指針與指向11元素?cái)?shù)組的指針的類(lèi)型不同T)。
當(dāng)數(shù)組表達(dá)式作為操作&
符的操作數(shù)出現(xiàn)時(shí),結(jié)果表達(dá)式的類(lèi)型是“指向T的N元素?cái)?shù)組的指針”,或者T (*)[N]
,它與指針數(shù)組(T *[N]
)和指向基類(lèi)型的指針不同(T *
)。
在處理函數(shù)和指針時(shí),要記住的規(guī)則是:如果要更改參數(shù)的值并將其反映在調(diào)用代碼中,則必須將指針傳遞給要修改的事物。同樣,數(shù)組會(huì)投入一些動(dòng)作,但我們會(huì)首先處理正常情況。
請(qǐng)記住,C 按值傳遞所有函數(shù)參數(shù); 形式參數(shù)接收實(shí)際參數(shù)中值的副本,并且形式參數(shù)的任何更改都不會(huì)反映在實(shí)際參數(shù)中。常見(jiàn)的例子是交換功能:
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
形式參數(shù)x
和y
從不同的對(duì)象a
和b
,所以要改變x
和y
未在反射a
和b
。因?yàn)槲覀円薷牡闹?code>a和b
,我們必須通過(guò)指針,以他們的交換功能:
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);
現(xiàn)在您的輸出將是
在交換之前:a = 1,b = 2交換后:a = 2,b = 1
請(qǐng)注意,在交換函數(shù)中,我們不會(huì)更改x
and y
的值,而是更改what x
和y
指向的值。寫(xiě)作*x
不同于寫(xiě)作x
; 我們沒(méi)有更新價(jià)值x
本身,我們從該位置獲取位置x
并更新該位置的值。
如果我們想要修改指針值,這同樣適用; 如果我們寫(xiě)
int myFopen(FILE *stream) {stream = fopen("myfile.dat", "r"); }...FILE *in;myFopen(in);
然后我們修改輸入?yún)?shù)的值stream
,而不是stream
指向stream
的值,因此更改對(duì)值的影響沒(méi)有影響in
; 為了使其工作,我們必須傳入一個(gè)指針指針:
int myFopen(FILE **stream) {*stream = fopen("myFile.dat", "r"); }...FILE *in;myFopen(&in);
再次,陣列投入了一些猴子扳手。將數(shù)組表達(dá)式傳遞給函數(shù)時(shí),函數(shù)接收的是指針。由于如何定義數(shù)組下標(biāo),您可以在指針上使用下標(biāo)運(yùn)算符,就像在數(shù)組上使用它一樣:
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;}
請(qǐng)注意,可能未分配數(shù)組對(duì)象; 即,你不能做類(lèi)似的事情
int a[10], b[10];...a = b;
所以當(dāng)你處理指向數(shù)組的指針時(shí)要小心; 就像是
void (int (*foo)[N]){ ... *foo = ...;}
不行。
- 3 回答
- 0 關(guān)注
- 781 瀏覽
添加回答
舉報(bào)