C++Review14_数组参数和指针参数

一、数组参数:

 1 //数组作为参数,编译器会把它解释为一个指向其首元素首地址的指针;
 2 void func(char a[],int length){
 3     //a表示的是首元素的首地址,a+3表示的是数组第三个元素的首地址
 4     //数组下标和指针形式访问都行;
 5     cout<<a[3]<<endl;
 6     cout<<*(a+3)<<endl;
 7     *(a+3) ='o'; //*(地址) 就能访问和修改这个地址上的值了,也就是访问和修改数组的某个元素了;
 8 }
 9 
10 int main()
11 {
12     //其实就是拷贝了一个指针,但是修改的是同一份数组
13     char b[5] = "abcd";
14     func(b,5);
15     cout<<b[3]<<endl;
16     return 0;
17 
18 
19 }

所以数组是没有副本拷贝进函数的。拷贝的只是一个指向数组首元素首地址的指针;通过该指针来操作原始的数组;

数组没有进行拷贝是因为这样做的开销很大。很多情况下我们并需要整个数组的拷贝;

所以不拷贝数组,节省了空间和时间,提高了程序运行的效率;

 

二、指针参数:

 1 void func(const char *p){
 2     char c = p[3];  //也可以使用*(p+3)
 3     cout <<c<<endl;
 4     cout <<"Address of p "<<&p<<endl;
 5     cout <<"Value of p:"<<p<<endl;
 6 }
 7 
 8 int main()
 9 {
10     const char *ptr = "adcde";
11     cout <<"Address of ptr "<<&ptr<<endl;
12     cout <<"Value of ptr:"<<ptr<<endl;
13     func(ptr);
14 
15     char a = 'a';
16     char * char_ptr = &a;
17     cout <<"Value of char_ptr:"<<char_ptr<<endl;
18 
19     int  num = 5;
20     int * num_ptr = &num;
21     cout <<"Value of num_ptr:"<<num_ptr<<endl;
22     return 0;
23 
24 }

 

C++Review14_数组参数和指针参数

 

 

首先可以看到,指针作为参数,其实是拷贝了一份指针。不过所指向的是同一块内存地址;

 

这里还发现一个现象,如果指针是指向字符类型的变量,指针被赋值后,直接打印指针的话,显示的是所指的字符串,而不是地址;

如果换成指向int的指针,被赋值后,直接打印指针的话,显示的所指int变量的地址;

按理说直接打印指针变量,应该显示地址才是,这块有待探究。

 

三、二级指针参数

如果我们想把指针变量本身传递仅函数呢?

这时候就要用到二级指针,即指向指针的指针;

实际上的意思就是我们还是拷贝了参数,但是拷贝的是二级指针。通过二级指针可以操作这个传递进来的指针变量(一级指针);

这种一般用在,我如果在一个函数中申请了块内存,那么我希望在函数结束后,外界还能管控这个内存。那就必须传递一个指针进去,函数的参数用二级指针。

这就保证了传递进去的指针可以指向所申请的内存。不会导致内存泄漏了。

 

 1 void func(int **p){  //实际上我们拷贝的是一份一级指针的地址,p是一个二级指针
 2 
 3     //这行语句就是对一级指针赋值;
 4     *p = new int(5); //*p的含义:首先p是一个指向int *类型的指针。对二级指针p(p的值是一级指针的地址)解引用,会得到一级指针的值(所指变量的地址);
 5     cout<<"p: "<<p<<endl;  //二级指针的值
 6 }
 7 
 8 int main()
 9 {
10     int * ptr;  //我们的一级指针
11     cout<<"& ptr: "<<&ptr<<endl;  //一级指针的地址
12     func(&ptr); //这里要注意,是对一级指针取址,把地址告知func,func获得了一份地址的拷贝,是一级指针的地址;
13 
14     //这时候指针指向新分配的内存空间,打印一下指针所指变量的值,
15     cout<<*ptr<<endl;
16 
17     delete ptr; //安全释放内存空间
18     return 0;
19 
20 }

 

C++Review14_数组参数和指针参数

 

四、二维数组参数与二维指针参数

void fun(char a[3][4]);  //二维数组本质上是一个一维数组a[3],只不过每个元素是一个数组,4个char元素的数组;当一维数组作为函数参数时,编译器会把它解释成一个指向首元素首地址的指针;

可以改写成:

void fun(char (*p)[4]);   //这里括号不能省略,编译器会把p解释成一个指针,一个指向包含4个char类型数据元素的数组,即一维数组a[3]的元素;

还可以这样写:

void fun(char a[][4]);    //这里的4为什么不能省略呢?

因为当一维数组作为参数时,编译器总是把它解析成一个指向首元素首地址的指针。但是这个规则不能递归,也就是超过一维后,后面的维再也不可改写;

 

另外:

char *p[5];    //指针数组

作为参数时,可等效为:

char **p;     //指针的指针;同样还是基于一维数组可等效成指向首元素首地址的指针

原文链接: https://www.cnblogs.com/grooovvve/p/12370698.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    C++Review14_数组参数和指针参数

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/332224

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年3月1日 下午6:24
下一篇 2023年3月1日 下午6:24

相关推荐