指针一直是个让人头疼的问题,对于C系来说,不学好指针,就没有学到精髓,最近写一个链表的练习,发现const指针的一些问题,构造了一些函数进行测试。
构造结构体:
typedef struct Node
{
int d;
Node * next;
}MyNode,*MyPoint;
测试结点:
MyNode n;
n.d = 4;
n.next = NULL;
MyNode * t;
t= &n;
首先讨论const在变量类型之前的情况
一、 首先是const的常量:
//************结构体的const 引用*******************************
void changeStruct(const MyNode & pm)
{
// pm.d = 3;
MyNode nw;
nw = pm;
nw.d = 1;
printf("changestruct中的值:%d\n",pm.d);
}//main函数中的原值不变
const的常量可以赋值给非const的变量,const的常量不可修改,const引用对于原值没有修改,不进行值拷贝。效率高,一般用在对象的操作上。如果对象较大,复制拷贝及析构较费时间,可使用const引用提高效率。
测试用例:
//*********结构体与指针*************//
printf("在main中的值");
printf("%d\n",n.d);
changeStruct(n);
printf("在main中的值");
printf("%d\n",n.d);
结果:
在main中的值4
changestruct中的值:4
在main中的值4
二、const结构体的指针
//*****************const结构体的指针**********************
void changePoint_1(const MyNode * pt)
{
MyNode p;
p = * pt;
printf("复制后的mynode 的data值:%d",p.d);
p.d = 1;
printf("更改后的值:%d",pt->d);
MyNode * pmt;
//没有分配内存不可以用
//pmt = pt;
//pmt->d = pt ->d;
//pmt->next = pt->next;
pmt = (MyNode*) malloc(sizeof(MyNode));
//对内容逐个进行值拷贝
pmt->d = pt ->d;
pmt->next = pt->next;
}//main函数中的原值不变
测试用例:
printf("在main中的值:");
printf("%d\n",n.d);
changePoint_1(&n);
printf("在main中的值:");
printf("%d\n",n.d);
结果:
在main中的值:4
复制后的mynode 的data值:4
更改后的值:4
在main中的值:4
对于const MyNode * 来说,const的MyNode不可以修改,指针只能赋给const 类型的指针。当遇到MyNode * pm = pt时, 有:error C2440: “=”: 无法从“const MyNode *”转换为“MyNode *”。如果赋值给非const的指针时,可能会对原值进行修改。
而对于MyPoint来说,虽然MyNode*与MyPoint实质上是同一个类型但是却操作起来不同,const MyNode*不能修改结构体,而const MyPoint不能修改指针,测试如下:
//**************结构体指针,将指针里的地址复制了一份
void changePoint_2(const MyPoint pt)
{
MyPoint m = pt;//const常量可以赋值给非const常量
pt->d = 5;
printf("change 指针的值%d\n",pt->d);
printf("指针的地址%d\n",&pt);
printf("指针的值%d\n",pt);
}
测试用例:
printf("指针的地址%d\n",&t);
printf("指针的值%d\n",t);
changePoint_2(t);
printf("在main中的值");
printf("%d\n",n.d);
结果:
指针的地址1245008
指针的值1245020
changepoint_2的值5
指针的地址1244796
指针的值1245020
在main中的值5
可以看出指针的值没有变,指针的值存的就是结构体的地址,函数中,可以对结构体的值进行直接修改,而不能改变指针的值,即结构体的地址。
三、const结构体的引用
//***************结构体指针的引用 可以修改指针的值,不能修改MyNode的值
void changePointRefer(const MyNode * & pt)
{
//pt->d = 4;
MyNode * t;
MyNode n = *pt;
//pt = NULL;
n.d = pt->d;
printf("change 指针引用的值%d\n",pt->d);
printf("指针的地址%d\n",&pt);
printf("指针的值%d\n",pt);
}//只能修改指针的值,不能赋给非const的指针,或者修改node的值。
//*************指针的引用const的是MyNode *,指针指向的地址不能变,该地址里的内容可以变,就对本指针操作
void changePointRefer_2(const MyPoint & pt)
{
pt->d = 6;
MyPoint pp;
pp = pt;
pp->d = 19;
// pt = NULL;
printf("change 结构体指针的引用%d\n",pt->d);
printf("指针的地址%d\n",&pt);
printf("指针的值%d\n",pt);
}
这两个函数与上面的两个效果相同,唯一不同就是指针地址是否改变,引用不复制指针的值,直接对指针进行操作,而值传递,传递的是指针的内容,即结构体的地址,而指针的地址发生改变。
对changePointRefer_2的测试用例
测试用例:
printf("指针的地址%d\n",&t);
printf("指针的值%d\n",t);
changePointRefer_2(t);
printf("在main中的值");
printf("%d\n",n.d);
结果:changePointRefer_2
指针的地址1245008
指针的值1245020
change 结构体指针的引用19
指针的地址1245008
指针的值1245020
在main中的值19
可以看到是直接对指针的操作,指针的地址都没有变化。
对changePointRefer的测试:
const MyNode * t =&n;
printf("指针的地址%d\n",&t);
printf("指针的值%d\n",t);
changePointRefer(t);
printf("在main中的值");
printf("%d\n",n.d);
结果:
指针的地址1244996
指针的值1245020
change 指针引用的值4
指针的地址1244996
指针的值1245020
在main中的值4
可以看到指针地址没有变化,是对指针的操作,但是changePointRefer传参数必须要是const类型的???
补充:对于typedef类型来说,const MyPoint相当于MyNode * const ,const的后移。