void change(char *string){
string = "Hello";
printf("%s", string);
}
int main (void){
char* s = "Hey";
change(s);
printf("%s", s);
return 0;
}
上面的代碼不應該列印“Hello”嗎,因為傳遞給函式的引數是一個指標?
uj5u.com熱心網友回復:
如果要參考指標,請傳遞 char**。然后您可以更改 main 中的指標指向的位置。
uj5u.com熱心網友回復:
有幾種方法可以做你想做的事。最常見的如下所示。可能值得對此進行調查以了解正在發生的事情:
#include <stdio.h>
#include <string.h>
void
change(char const **string)
{
*string = "Hello";
}
void
change2(char * string, size_t n)
{
strncpy(string, "hello", n - 1);
}
int
main(void)
{
char const *cs = "Hey";
char * s;
char buf1[32] = "ABC";
char buf2[] = "XYZ";
change(&cs);
change2(s = buf1, sizeof buf1);
change2(s = buf2, sizeof buf2);
return 0;
}
uj5u.com熱心網友回復:
不,您的代碼不應僅僅因為您有一個指標(指向字串的第一個位元組)而列印“Hello” 。
你的代碼實際上做了什么?
考慮這個示例記憶體布局:
0 1 2 3
0x1000 : 'H' | 'e' | 'y' | x00
0x1004 : 'H' | 'e' | 'l' | 'l'
0x1008 : 'o' | x00 | xFE | xFE
字串文字的位元組0x1000從地址開始,0x1000字串文字的位元組"Hello"從地址開始0x1004。它們甚至可以存盤在只讀存盤器中。
char* s = "Hey";
s是一個存盤地址的變數。它是0x1000記憶體中的地址(指向 的指標"Hey")。
change(s);
void change(char *string){
當您呼叫時,change您將值傳遞s給函式并將其分配給引數string。這幾乎就像在說string = s。因此,在函式內部,string現在也包含地址0x1000。
該引數的string作業方式類似于區域變數,您可以更改它的值。請記住,它的值只是一個地址。更改此值不會更改字串的位元組。
string = "Hello";
您分配string值0x1004(指向 的指標"Hello")。此時變數s仍然包含該值0x1000,并且它仍然是0x1000呼叫后的值change。但是變數string現在具有0x1004指向字串第一個位元組的值"Hello"。
當您傳遞s給printf您時,您要求它在存盤的地址處列印字串,該地址s仍然是地址0x1000,因此您列印Hey。
如果你真的想改變s怎么辦?
s如果您希望能夠修改它,則可能會傳遞變數本身的地址。由于sis 是 type char*,指向的指標s將是 type char**。
char* s = "Hey";
char** ptr = &s;
(*ptr) = "Hello";
printf("%s", s);
(為簡潔起見,我在沒有函式呼叫的情況下撰寫了上面的代碼,但是您可以輕松地創建函式void change(char** ptr)并呼叫change(&s)。)
為了可視化這一點,我們需要包括存盤s在記憶體中的位置,并同意存盤記憶體地址需要多少位元組。在我想象的示例平臺中,記憶體地址是 2 個位元組。(sizeof void* 為 2,地址以小端序存盤(最低有效位元組在前))
請注意,指標(記憶體地址)的大小取決于您的平臺。它可以是 4 位元組(在 32 位架構上)甚至是 8 位元組(在 64 位架構上)。
0 1 2 3
0x1000 : 'H' | 'e' | 'y' | x00
0x1004 : 'H' | 'e' | 'l' | 'l'
0x1008 : 'o' | x00 | xFE | xFE
0x100C : x00 | x10 | xFE | xFE
該變數s存盤在記憶體中的位置0x100C(在這個假想的情況下它有 2 個位元組長,所以它也占用了 處的位元組0x100D)。它的初始值為0x1000(指向"Hey")
ptr = &s;
現在ptr保存值0x100C(的地址s)
(*ptr) = "Hello";
現在s持有價值0x1004。并且地址0x100C和位元組處的位元組0x100D被更新以存盤地址0x1004。
0x100C : x04 | x10 | xFE | xFE
s現在包含值0x1004并指向字串的第一個位元組"Hello"。請注意,我們從來沒有修改字串文字本身的位元組——它們是恒定的。我們只是在操縱地址。
完整示例:
void change(char **pString){
(*pString) = "Hello";
printf("%s", (*pString));
}
int main (void){
char* s = "Hey";
change(&s);
printf("%s", s);
return 0;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/519689.html
標籤:C细绳功能指针
