解析C/C++值傳遞和址傳遞的區(qū)別
C/C++的按值傳遞和按地址傳遞有明顯不同,下面對他們作個(gè)區(qū)別:
按值傳遞:在調(diào)用函數(shù)中將原函數(shù)的值拷貝一份過去被調(diào)用的函數(shù),在被調(diào)用函數(shù)中對該值的修改不會影響原函數(shù)的值。
按地址傳遞:在調(diào)用函數(shù)的時(shí)候?qū)⒃瘮?shù)的值所在的地址拷貝一份過去,被調(diào)用函數(shù)對這個(gè)地址所作的修改會影響原來的值。
概述:
首先我們要知道 “a的地址”和“a地址中的內(nèi)容”的區(qū)別,數(shù)據(jù)是存放在內(nèi)存中的,每一個(gè)變量都有一個(gè)內(nèi)存地址, 變量的內(nèi)容存放在對應(yīng)內(nèi)存地址的空間中
比方說定義
int a = 10;
那么a在內(nèi)存中的地址是0x1100,在這個(gè)地址中存儲的數(shù)據(jù)是10

假設(shè)創(chuàng)建指針p,把a(bǔ)的地址賦值給p,就是把a(bǔ)的首地址0x1100賦值給指針p,這個(gè)時(shí)候p的值就是變量a在內(nèi)存中的首地址
int a =10; int*p; p=&a; //把a(bǔ)的首地址賦值給P

簡單點(diǎn)的理解就好比你去圖書館借書,每本書都會有他的一個(gè)編號(地址),記錄它所在的位置,而這個(gè)書,就是這個(gè)地址對應(yīng)的內(nèi)容,
如果你用指針,得到的是這個(gè)書所對應(yīng)的編號(地址) ,存儲內(nèi)容就是地址
如果你是變量賦值,值傳遞,那么就相當(dāng)于復(fù)印了一遍這個(gè)書(地址對應(yīng)的內(nèi)容),然后用一個(gè)新的編號(地址),去存儲你復(fù)印的這本書

從命名來理解
所以我們就會發(fā)現(xiàn):
值傳遞,或者變量賦值,修改變量的值,修改的是新的新的編號(地址)中的內(nèi)容(復(fù)印的書),不會影響到原來編號(地址)中的數(shù)據(jù)。
也就是形參是實(shí)參內(nèi)容的拷貝,并不是地址的拷貝,所以改變形參的值并不會影響實(shí)參的值

使用址傳遞,用指針修改變量的值,就是把原編號(地址)中的書給修改了,換了一本新的書,就相當(dāng)于對實(shí)參本身進(jìn)行的操作。
聲明Declaration:描述在其他地方創(chuàng)建的對象,并不分配內(nèi)存。(可以出現(xiàn)在多個(gè)地方)
定義Definition:產(chǎn)生一個(gè)新的對象,并分配內(nèi)存。(只能出現(xiàn)一次)
值傳遞
新開辟一個(gè)內(nèi)存空間,存儲原來變量的值,修改變量修改的是新的內(nèi)存空間中的值。所以,原始的參數(shù)不會被函數(shù)修改。
值傳遞的優(yōu)點(diǎn): 通過值來傳遞的參數(shù)可以是數(shù)字,變量,表達(dá)式。原本參數(shù)的值不會被修改。
值傳遞的缺點(diǎn): 不能修改原參數(shù)的值。
#include <stdio.h>
void swap (int x, int y)
{
int temp;
temp = x;
x = y;
y = temp;
// printf ("x = %d, y = %d\n", x, y);
}
int main (void)
{
int a = 4, b = 6;
printf ("交換前:\n a = %d, b = %d\n", a, b);
swap (a, b);
printf ("交換后:\n a = %d, b = %d\n", a, b);
return 0;
}
輸出:

址傳遞
址傳遞就是指針傳遞,形參實(shí)際是指向?qū)崊⒌刂返闹羔槪?dāng)對形參的進(jìn)行操作時(shí),就相當(dāng)于對實(shí)參本身進(jìn)行的操作,可以改變指針指向內(nèi)容的值,但是不能改變指針本身的地址。
#include <stdio.h>
void swap (int *x, int *y)
{
int temp=*x;
*x=*y;
*y=temp;
//printf("x = %d, y = %d\n", *x, *y);
}
int main(void)
{
int a=4;
int b=6;
printf("交換前:\n a = %d, b = %d\n", a, b);
swap (&a,&b); //傳遞的是地址
printf("交換后:\n a = %d, b = %d\n", a, b);
return 0;
}

在你了解了什么是值傳遞和址傳遞之后,我們來看一個(gè)面試題:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void GetMemory( char *p ) {
p = (char *) malloc( 100 );
}
int main (void) {
char *str = NULL;
GetMemory( str );
strcpy( str, "hello world" );
printf( str );
return 0;
}
請問運(yùn)行會有什么樣的結(jié)果? 會輸出hello world嗎?
答:程序崩潰,沒有輸出
因?yàn)?GetMemory 并不能傳遞動(dòng)態(tài)內(nèi)存,Test 函數(shù)中的 str 一直都是 NULL。strcpy(str, “hello world”);將使程序崩潰
函數(shù)中的p其實(shí)是實(shí)參str的一份拷貝,函數(shù)中的操作都是對q進(jìn)行的,str仍然是NULL,所以輸出*str的值產(chǎn)生崩潰
也就是:傳遞給形參的指針仍然是實(shí)參指針的一份拷貝

這一點(diǎn)需要注意
解決的話可以把形參改為二重指針,程序便可以按預(yù)想中的情形進(jìn)行:
二重指針指向一重指針的地址 也就是傳遞過來的實(shí)際是*str的參數(shù)本身
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void GetMemory( char **p ) {
*p = (char *) malloc( 100 );
}
int main (void) {
char *str = NULL;
GetMemory(&str);
strcpy( str, "hello world" );
printf( str );
return 0;
}
到此這篇關(guān)于解析C/C++值傳遞和址傳遞的區(qū)別的文章就介紹到這了,更多相關(guān)C/C++值傳遞和址傳遞內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語言動(dòng)態(tài)內(nèi)存管理分析總結(jié)
C語言中開辟內(nèi)存有很多種方式,目前我們最常用的也就是數(shù)組,但數(shù)組是在我們用到他之前就得設(shè)定好它的長度,有時(shí)很不方便。隨意我們來探究動(dòng)態(tài)內(nèi)存管理2021-11-11
Visual Studio Code 從簡介、安裝到配置所需插件詳細(xì)介紹
這篇文章給大家介紹到vs與vs code的區(qū)別,并且會詳細(xì)介紹vscode的安裝步驟,和我所了解過的插件配置,感興趣的朋友跟隨小編一起看看吧2020-03-03
從頭學(xué)習(xí)C語言之for語句和循環(huán)嵌套
這篇文章主要為大家詳細(xì)介紹了C語言之for語句和循環(huán)嵌套,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-01-01
C++實(shí)現(xiàn)教職工管理系統(tǒng)課程設(shè)計(jì)
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)教職工管理系統(tǒng)課程設(shè)計(jì),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03
Qt鍵盤事件實(shí)現(xiàn)圖片在窗口上下左右移動(dòng)
這篇文章主要為大家詳細(xì)介紹了Qt鍵盤事件實(shí)現(xiàn)圖片在窗口上下左右移動(dòng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08

