日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

一个传值的问题”*”与”*”

發(fā)布時(shí)間:2023/12/10 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一个传值的问题”*”与”*” 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
1/*********************************************************
2* Desc:參數(shù)傳遞:使用引用傳遞指針和直接傳遞指針地址的區(qū)別
3* Author:charley
4* DateTime:2010-12-7 11:00
02***********************************************************/
03#include <iostream>
04using namespace std;
05??
06/*
07函數(shù)聲明
08*/
09void swapByRef(int *&,int *&);
10void swapByPoi(int *,int *);
11??
12int main(void)
13{
14????inti=10;
15????intj=20;
16????int*pi=&i; //pi指向i所在的內(nèi)存地址
17????int*pj=&j;//pj指向j所在的內(nèi)存地址
18??????
19????//通過引用傳遞參數(shù),傳遞的是指針本身
20????cout<<"調(diào)用swapByRef()之前:pi="<<pi<<",*pi="<<*pi<<";pj="<<pj<<",*pj="<<*pj<<endl;
21????swapByRef(pi,pj);
22????cout<<"調(diào)用swapByRef()之后:pi="<<pi<<",*pi="<<*pi<<";pj="<<pj<<",*pj="<<*pj<<endl;
23??????
24????cout<<"**********************"<<endl;
25??
26????//通過指針來傳遞參數(shù),傳遞的是指針地址
27????cout<<"調(diào)用swapByPoi()之前:pi="<<pi<<",*pi="<<*pi<<";pj="<<pj<<",*pj="<<*pj<<endl;
28????swapByPoi(&i,&j);
29????//或者直接 swapByPoi(pi,pj);
30????cout<<"調(diào)用swapByPoi()之后:pi="<<pi<<",*pi="<<*pi<<";pj="<<pj<<",*pj="<<*pj<<endl;
31??
32????getchar();
33????return0;
34}
35??
36/*
37通過引用傳遞參數(shù):
38參數(shù)為整型指針的引用,
39引用是指針的一個(gè)別名,傳遞時(shí)不需要在內(nèi)存中分配空間來接收參數(shù)
40參考:swapByRef(int &v1,int &v2)
41*/
42void swapByRef(int *&v1,int *&v2)
43{
44????int*temp=v1;//指針賦值,指針執(zhí)行的地址變化了
45????v1=v2;
46????v2=temp;
47}
48??
49/*
50通過指針來傳遞參數(shù):
51參數(shù)為整型指針變量
52內(nèi)存存需要為形參分配空間來接收傳進(jìn)來的指針地址
53參考:swapByPoi(int v1,int v2)
54*/
55void swapByPoi(int *v1,int *v2)
56{
57????inttemp=*v1; //操作指針指向的內(nèi)容,指針執(zhí)行的地址未變化
58????*v1=*v2;
59????*v2=temp;
60}

執(zhí)行結(jié)果:

?

從結(jié)果可以看出:

1. swapByRef方法是直接交換參數(shù)的指針執(zhí)行的地址,所以指針指向的內(nèi)容也換了

2. swapByPoi方法只是操作指針指向的內(nèi)容,指針執(zhí)行的地址未變化

?

?

#include <stdio.h>

void swap(int x,int y)//這是錯(cuò)誤的寫法
{
int temp;
temp=x;
x=y;
y=temp;
}

int main()
{
int a=5,b=8;
swap(a,b);
printf("%d %d\n",a,b);
return 0;
}

代碼很容易理解,就是交換2個(gè)變量a和b的值并輸出,但是運(yùn)行后我們發(fā)現(xiàn)輸出結(jié)果不是"8 5"而依舊是"5 8",也就是說交換函數(shù)并沒有將2個(gè)變量的值交換,這是為什么呢?

我們知道,C語言中整型變量的形式參數(shù)傳遞的是值而不是地址,也就是形式參數(shù)實(shí)際上是復(fù)制了實(shí)際參數(shù)的值進(jìn)入函數(shù)運(yùn)算的,而被復(fù)制的實(shí)際參數(shù)的值并沒有改變。就這段代碼來說,就是形參x復(fù)制了a的值變成5,形參y復(fù)制了b的值變成8,然后在swap函數(shù)中進(jìn)行交換,使得x=8,y=5,但實(shí)際上a和b的值并沒有被交換,這也就是為什么這段代碼并沒有實(shí)現(xiàn)交換的原因。

那么怎么解決呢?

先前我們說了C語言中整型變量的形式參數(shù)傳遞的是值而不是地址,那么現(xiàn)在我們就讓它傳遞地址,直接交換實(shí)際參數(shù)的值。

#include <stdio.h>

void swap(int *x,int *y)//使用指針傳遞地址
{
int temp;
temp=*x;
*x=*y;
*y=temp;
}

int main()
{
int a=5,b=8;
swap(&a,&b);
printf("%d %d\n",a,b);
return 0;
}

我們使用指針變量來進(jìn)行地址傳遞,形式參數(shù)為變量a和b的地址,swap函數(shù)直接交換a和b的地址所指向的值。這里一定注意形式參數(shù)傳遞的是地址而不是值

?

?

?

C++引用&和指針在作為形參時(shí)的區(qū)別

int n;

int &m = n;

在C++中,多了一個(gè)C語言沒有的引用聲明符&,如上,m就是n的引用,簡單的說m就是n的別名,兩者在內(nèi)存中占同樣的位置,不對m開辟新的內(nèi)存空間,對m的任何操作,對n來說是一樣的。

對于引用,有以下三條規(guī)則:

(1)引用被創(chuàng)建的同時(shí)必須被初始化(指針則可以在任何時(shí)候被初始化)。
(2)不能有NULL 引用,引用必須與合法的存儲單元關(guān)聯(lián)(指針則可以是NULL)。
(3)一旦引用被初始化,就不能改變引用的關(guān)系(指針則可以隨時(shí)改變所指的對象)。

?

假如在一個(gè)函數(shù)中動(dòng)態(tài)申請內(nèi)存空間,用指針和用引用作形參會(huì)得到不同的結(jié)果,如下面的例子:

void fun(int* b){? //用指針做形參
?b = (int*)malloc(sizeof(int)*3);

?for(int i=0; i<3; i++){
??a[i] = i;
?}
}

void fun(int* &b){??//用引用做形參
?b = (int*)malloc(sizeof(int)*3);

?for(int i=0; i<3; i++){
??b[i] = i;
?}
}

如果在main函數(shù)中定義了一個(gè)int型的空指針并分別作為實(shí)參傳入,如下:

int main(){
?int *a = NULL;

?fun(a);

?for(int i=0; i<3; i++){
??cout << a[i] << " ";
?}
?cout << "\n";

?return 0;
}

結(jié)果用指針的函數(shù)會(huì)出現(xiàn)內(nèi)存訪問出錯(cuò),用引用的函數(shù)則運(yùn)行正常并正確輸出1 2 3.

這是因?yàn)?#xff1a;

1.指針雖然是地址傳遞,但實(shí)際上也是在函數(shù)中又定義了一個(gè)新的指針讓其與傳入的指針指向同一地址。但兩個(gè)指針本身作為變量在內(nèi)存中的存放地址是不同的,就是說這是兩個(gè)不同的變量,只是內(nèi)容(即所指地址)相同。

2.在函數(shù)中對新定義的指針動(dòng)態(tài)申請內(nèi)存,但是當(dāng)函數(shù)結(jié)束后,申請的內(nèi)存的生命周期也就結(jié)束了,所以當(dāng)回到主函數(shù)時(shí),作為實(shí)參的指針地址和內(nèi)容都沒有變化。仍然是個(gè)空指針,對其進(jìn)行訪問自然出現(xiàn)了內(nèi)存讀錯(cuò)誤了。

假如在main函數(shù)中這樣寫:

int *a = (int*)malloc(sizeof(int)*3);

就不會(huì)出現(xiàn)內(nèi)存讀錯(cuò)誤了,但是輸出結(jié)果還是錯(cuò)誤的,道理也是一樣的。

3.用引用作為實(shí)參傳入時(shí),fun函數(shù)中的b其實(shí)就是主函數(shù)中a的別名(或者叫外號),反正就是操作完全相同,地址相同,內(nèi)容相同的一個(gè)變量,所以當(dāng)fun函數(shù)返回時(shí),對b的操作在主函數(shù)中對a同樣有效。

?

再看一個(gè)例子:

int *a = NULL;

char* b = (char*)a;

?

int *a = NULL;

char* &b = (char*)a;

這一次是在編譯階段的區(qū)別:

用指針可以通過編譯,而用引用則不可以,提示類型轉(zhuǎn)換出錯(cuò)。

?

通過這兩個(gè)例子可以看出,指針比引用靈活,也更加危險(xiǎn)。

?

摘自『高質(zhì)量c++編程』
條款一:指針與引用的區(qū)別
指針與引用看上去完全不同(指針用操作符’*’和’->’,引用使用操作符’.’),但是它們似乎有相同的功能。指針與引用都是讓你間接引用其他對象。你如何決定在什么時(shí)候使用指針,在什么時(shí)候使用引用呢?
首先,要認(rèn)識到在任何情況下都不能用指向空值的引用。一個(gè)引用必須總是指向某些對象。因此如果你使用一個(gè)變量并讓它指向一個(gè)對象,但是該變量在某些時(shí)候也可能不指向任何對象,這時(shí)你應(yīng)該把變量聲明為指針,因?yàn)檫@樣你可以賦空值給該變量。相反,如果變量肯定指向一個(gè)對象,例如你的設(shè)計(jì)不允許變量為空,這時(shí)你就可以把變量聲明為引用。

?

PS:引用在定義時(shí)不可加const,否則編譯出錯(cuò),在形參前面則可以加const以確保在函數(shù)中該變量不會(huì)被修改。

?

個(gè)人認(rèn)為:其實(shí)形參建立的是一個(gè)新的地址,只是這地址是實(shí)參內(nèi)容的一個(gè)COPY,假如實(shí)參為p,形參就為_p;

總結(jié)

以上是生活随笔為你收集整理的一个传值的问题”*”与”*”的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。