const与指针(一)

来源:互联网 发布:大数据的分析方法 编辑:程序博客网 时间:2024/05/22 05:24

  指针一直是个让人头疼的问题,对于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的后移。