在 C 中通過參考傳遞指標和通過值傳遞指標有什么區別?
我的理解是,當您將引數傳遞給方法時,會創建一個新的堆疊框架,并且這些值將被復制到不同的記憶體地址,除非通過參考傳遞。如果通過參考傳遞記憶體地址。
使用指標時,我注意到如果我按值傳遞 char* 并在回傳主堆疊幀時在不同的堆疊幀中修改它,則 ptr 的值已被修改。
我寫了簡短的代碼來顯示我在說什么。
//test pointer ref
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void passbyval(char const *lit,char* str){
printf("---passbyval---\n");
printf("%s\t%p\n",lit,&lit);
//modify string
strncat(&str[2],"/",1);
printf("%s\t%p\n",str, &str);
}
void passbyref(char const **lit, char** str){
printf("---passbyref---\n");
printf("%s\t%p\n",*lit,&*lit);
//modify string
strncat(&(*str)[1],"/",1);
printf("%s\t%p\n",*str,&*str);
}
int main(){
char const *litstr = "hello this is a test";
char *str = (char*)malloc(sizeof(char)*100);
scanf("%[^\n]",str);
printf("---main---\n");
//print original value and address
printf("%s\t%p\n",litstr,&litstr);
printf("%s\t%p\n",str,&str);
passbyval(litstr,str);
//modified value and address from pass by value
printf("\nretfromval:%s\t%p\n",str,&str);
passbyref(&litstr,&str);
//modified value and address from pass by ref
printf("\nretfromref:%s\t%p\n",str,&str);
free(str);
return EXIT_SUCCESS;
}
輸出

不通過要在 void 方法中修改的參考 char* 是一種好習慣嗎?
如果指標參考的值是通過參考隱式傳遞的,為什么我會使用通過參考傳遞指標。
也許我錯過了一些可以更好地解釋這一點的東西?
謝謝!
uj5u.com熱心網友回復:
使用指標時,我注意到如果我按值傳遞 char* 并在回傳主堆疊幀時在不同的堆疊幀中修改它,則 ptr 的值已被修改。
你的例子都沒有這樣做。此外,您的任何代碼都不會列印litstror的值str。要列印指標的值,請&在所有printf呼叫中洗掉。然后你會看到呼叫例程和被呼叫例程中指標的值是相同的。
在 中main,printf("%s\t%p\n",litstr,&litstr);列印:
- 在記憶體中開始的字串,該地址是
litstr(because of%sandlitstr)的值和 litstr(因為%pand&litstr)的地址(不是值)。
同樣,printf("%s\t%p\n",str,&str);列印字串 atstr和str.
在 中passbyval,printf("%s\t%p\n",lit,&lit);列印 處的字串lit和 的地址lit。由于lit是 的引數passbyval,它有自己的地址,與 的地址不同litstr。如果您列印了litstrand的值lit,而不是它們的地址,您會看到它們是相同的。
同樣,printf("%s\t%p\n",str, &str);列印字串 atstr和str. strin引數passbyval的地址與strin的本地物件的地址不同main,但它們的值是相同的。
在 中passbyref,printf("%s\t%p\n",*lit,&*lit);列印 處的字串lit和 的地址*lit。既然lit是litstrin的地址main,*lit就是那個litstr,那么&*lit的地址也是litstr。的值litstr是*lit。
同樣,printf("%s\t%p\n",*str,&*str);列印字串 at*str和 的地址*str,即strin的地址main。
uj5u.com熱心網友回復:
在 C 中通過參考傳遞指標和按值傳遞指標有什么區別?
在 C 中沒有通過參考傳遞指標這樣的事情,所有變數都是按值傳遞的,甚至是指標。
我的理解是,當您將引數傳遞給方法時,會創建一個新的堆疊框架,并且這些值將被復制到不同的記憶體地址,除非通過參考傳遞。如果通過參考傳遞記憶體地址。
同樣,指標不是通過參考傳遞的,而是傳遞了存盤在指標中的值的副本,即它指向的地址,您可以通過更改函式內部指標的值來測驗這一點,并檢查它如何反映在原始指標上,擾流板,它沒有。
使用指標時,我注意到如果我按值傳遞一個 char并在回傳主堆疊幀時在不同的堆疊幀中修改它,則 ptr 的值已被修改。*
您傳遞的是一個地址,一個存盤一些資料的記憶體位置,當您更改存盤在該記憶體地址中的資料時,無論您在哪里執行,它都是永久的,實際上這是使用指標的優點之一, 以便您在宣告它的范圍之外更改某些變數的內容。
uj5u.com熱心網友回復:
您需要了解指標和陣列的作業原理。
pointer 是一個獨立的物件,有自己的參考,持有底層物件的參考。
char *p = "aaa";
print("%p\n", (void *)p); //prints the reference of the string literal "aaa"
print("%p\n", (void *)&p); //prints the reference of the pointer `p`
陣列是連續的記憶體塊。陣列衰減為指標。這些指標在記憶體中沒有物理表示,只是對陣列第一個元素的參考。
char p[] = "aaa";
print("%p\n", (void *)p); //reference of the first element
//of the array p the type is `char *`
//(pointer to char)
print("%p\n", (void *)&p); //reference of the first element of the
//array p the type is `char (*)[4]`
//(pointer to an array of 4 char elements)
uj5u.com熱心網友回復:
在 C 中通過參考傳遞指標和通過值傳遞指標有什么區別?
在 C 中,引數在傳遞給函式之前有多種預處理方式。
無處理
將引數的副本提供給函式。char *s = ...; puts(s);.puts()被給予s.通常的引數提升
引數int, unsigned, double, ...在將副本提供給函式之前被提升。float fl = 12.5f; printf("%g", fl);printf()被給予double 12.5.函式轉換為地址
Withtss_create(tss_t *key, tss_dtor_t dtor);,tss_dtor_t是函式指標型別void (*)(void*)。tss_create(... , foo)不接受函式foo()并傳遞它。而是傳遞函式地址的副本。陣列轉換到其第一元件的地址
隨著char s[] = "Hello; puts(s);,的副本&s[0]被傳遞到puts()。
現在,這些中的任何一個都像 OP 的參考傳遞嗎?
是的。
用
char *end[1]; strtod("123.4", end);,但從呼叫者的點,end在它調整整體通過strtod()等作用和氣味等從呼叫者的POV“按參考傳遞”。這在技術上仍然是“傳遞副本”,但副本是引數的第一個元素的地址。
除此之外,我沒有看到可比的“通過參考傳遞指標并在 C 中通過值傳遞指標”來找到差異。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/406078.html
標籤:
下一篇:將第二個索引后的所有位歸零
