C++,const型指针变量做形参实参变量的问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++,const型指针变量做形参实参变量的问题相关的知识,希望对你有一定的参考价值。

1、允许形参和实参都是const型的指针变量
2、允许形参和实参都是非const型的指针变量
3、不允许形参是const型指针变量,而实参是非const型指针变量,因为在函数执行过程中,形参的值是可以变化的,而形参和实参指向的都是同一单元。
4、允许形参是const型的指针变量,而实参是非const型的指针变量。

这是谭浩强C++上面的原话,我对前面三条都可以理解。第四条不可以理解。
我认为,在程序执行过程中,实参也可以发生变化,比如再次调用函数(形参所在的函数)的时候,实参就可以发生改变了。或者在使用递归的时候实参不是都在变化吗?
所以第四点就不成立了。

你这里const型的指针变量是指:常指针,还是 指向常对象的指针变量?
应该是指:指向常对象的指针变量
这样的话,应该是如下的情况:
1、允许形参和实参都是const型的指针变量
2、允许形参和实参都是非const型的指针变量
3、允许形参是const型指针变量,而实参是非const型指针变量
4、不允许形参是非const型的指针变量,而实参是const型的指针变量。(原因在于指向非const型变量的指针变量只能指向非const的对象)
你的3、4的情况是一样的,是不是打错了?
参考技术A 第四条的翻译函数为:void fun(int * const a);const修饰的指针变量a,表示a是const型的,意思是在函数体中,a的值(注意a是个指针)是不可以改变的。如果你在函数体中改变a的值,例如int temp=9;a=&temp;这样的操作是编译出错的。
但是至于你给a传递什么参数就无所谓了,不管是const类型的指针,或是非const类型的指针,都无所谓。它约束的只是在函数体内部的形参临时变量。
参考技术B 第四点的const你理解为,作为参数的指针不可以被改变即可,因为要是被调用的函数随便改了,岂不是出问题了,所以这个参数形式是const型的,而你调用是,随便传,比如函数显示textbox的值,你可以把textbox1的指针传给他,也可以把textbox2的指针传参,这2个textbox不就是实参嘛,而函数定义的,就是const的形参本回答被提问者采纳 参考技术C 如果函数带有指向const类型的指针-- 那么这种函数可以接收const类型的实参或者非const类型的实参,并且不能改变指针变量所指向变量的值,也就是不可以对实参内容作出更改. 。 参考技术D 4、允许形参是const型的指针变量,而实参是非const型的指针变量。
const型的指针变量所指向的地址没有变,
指针不关心它所指向的内存地址块中存的是什么,它只关心内存地址 。

指针做形参做局部变量以及内存分配

一级指针做形参:首先一定要明白形参和你传递参数的那个实参是两个不同的变量,即使同名也还依然不同。指针传递的是一个变量或者一个值的地址,但是它本身还是采用值传递的方式。即你不能使它指向另外一块地址,但是你可以改变它指向的空间里存的值。

二级指针做形参:二级指针也是传值,但是他指向的地址是个一维指针,所以可以改变二维指针指向的地址空间里的内容也就是要申请空间的一维指针,不能改变二维指针本身的值,即不能让他指向一个新的一维指针。所以二维指针传递的是一个一维指针。

具体看下面这个程序以及输出:

#include<stdio.h>
#include <malloc.h>
#include <string.h>

void GetMemory1(char *p)

//该函数的形参为字符指针,在函数内部修改形参并不能真正改变传入形参的实参值。
//因此在主函数中执行完下面两句之后
//char *str1 = NULL;
//GetMemory1(str1);
//str1仍然为NULL,因此会报内存错误,没有输出结果。
p = (char *)malloc(100);

//要记得使用指针变量时,每次分配空间后要判断是否分配成功。而且在主函数中使用之后记得释放内存,并置空
if (p == NULL)

printf("error memory");


/*但是上面的函数参数变为*char *&p就可以在主函数中正常输出了。
指针做形参也是采用值传递的方式,也就是会把指针的值-地址传过去,所以可以改变这个地址里的内容,
但是你不能改变指针的值,也就是指向的地址。但是引用就是变量的别名,所以可以改变指针的值,
所以就可以在函数里申请空间
*/

char *GetMemory2(void)

char p[] = "hello world";
return p; //p[]数组为函数内部局部变量,在函数返回后,内存已经被释放了,
//所以在主函数中调用该函数str2 = GetMemory2();输出的可能为乱码


void GetMemory3(char **p,int num)

*p = (char *)malloc(num);

//要记得使用指针变量时,每次分配空间后要判断是否分配成功。而且在主函数中使用之后记得释放内存,并置空
if (*p == NULL)

printf("error memory");


void main()

int n=0;
char *str1 = NULL;
char *str2 = NULL;
char *str3 = NULL;

//GetMemory1(str1);
//strcpy(str1,"Hello world");
//printf("%s\\n",str1);

str2 = GetMemory2();
printf("%s\\n",str2);//输出乱码

GetMemory3(&str3,100);
strcpy(str3,"hello world");
printf("%s\\n",str3);//输出hello world

char *str4 = (char *)malloc(100);
if (str4 == NULL)

printf("error memory");

else

strcpy(str4,"Hello");
free(str4);
str4 == NULL;//free后要置空,否则str可能变成“野指针”

if (str4 != NULL)

strcpy(str4,"world");
printf("%s\\n",str4);//输出world

scanf("%d",&n);

指针做局部变量:如果你申请了空间(用new等,赋值不算)又没有delete,那么这个空间在你程序运行结束之前不会释放,只要你知道这个空间的地址,就可以访问。这里的赋值不算是指,比如,你先定义一个数组,然后把数组名赋值指针。但是char *d = "ZET";这种形式相当于new了4个空间。

下面是中兴通讯2012校招笔试题目,问输出什么?

当时答错(狂汗),现在搞明白,在函数里写了注释:

#include <stdio.h>

//此函数中d也是个局部变量,函数执行完自动销毁,但是指针分配的空间不会被自动回收,除非程序员delete掉。
//所以这个可以正常输出。
char *a()

char *d = "ZET";//这个初始化的一种形式,相当于分配了四个空间
return d;


//但是第二个数组空间是系统维护的,函数执行完自动销毁
char *b()

char p[10] = "3G平台";
return p;



//参数是值传递方式,改变形参的地址,传递的实参的地址确不会因此改变
void c(int n,char *pName)

char *a[4] = "aaa","bbb","ccc","ddd";
pName = a[n];


void main()

int n=0;
char *pName = "DB";
printf("%s\\n",a());//输出ZET
printf("%s\\n",b());//随机输出乱码

c(2,pName);
printf("%s\\n",pName); //输出DB,因为char *pName = "DB";已经使得pName指向了DB,但c(2,pName);并不能改变pName指向的地址。
//形象点说就是:我有一个箱子给你用,你可以在里面装东西,但是你不能把我的箱子换成另外一个给我。
//在这里指的是不能函数调用不能使pName变成函数中的二维数组a。

scanf("%d",&n);

指针做形参,指针做局部变量,数组做形参,数组做局部变量之类的题目非常容易考到,而且容易迷糊,得不断学习...

以上是关于C++,const型指针变量做形参实参变量的问题的主要内容,如果未能解决你的问题,请参考以下文章

函数的使用

引用传参与指针传参的区别

传入参数 指针 引用和 什么都不加的区别

C++中const用法总结

指针做形参做局部变量以及内存分配

数组名作函数参数时,实参与形参变量之间的数据传递是?