0 backgroud
在coding的时候遇到一些const修饰的指针和对象,不清楚用法和意义,所以整理了一下。
1 指针类型
指针可以指向很多对象,整形,浮点形,结构体形等等。有时为了得到通用函数,可以设置指针为void形,而在使用的时候可以强制转为需要的形式。比如堆分配函数malloc/calloc函数:
void * malloc(size_t size);
int *pint = malloc(sizeof(int) * 10);
char *pchar = malloc(sizeof(char) * 10);
double *pdouble = malloc(sizeof(double) * 10);
这里可以看到,因为malloc()返回为void *形,所以在代码申请到堆的时候会隐式地转换为需要的类型。下面为一个简单的demo参考,其中p0是因为定义为 void*形,但是要printf输出所以要显式地进行类型转换。
// p0 是一个可指向任何类型的指针
void *p0;
int m0 = 0;
p0 = &m0;
printf("%d\n", *(int *)p0);
// p1 是一个可指向 int型的指针
int *p1;
int m1 = 1;
p1 = &m1;
printf("%d\n", *p1);
2 常量指针
关于常量指针,形式为const int* p;它指示着p不可以修改指向的数据的值(指向的数据为常量),下面有一个例子
int sizeof(void *p)
{
// blablablabla
}
int sizeof2(const void *p)
{
// blablablabla
}
sizeof 和 sizeof2 都是计算p的空间,显然这个函数是不需要,也是不可以修改p的数据的。那么我们可以把p用const修饰,这样在函数体内部就不可以对p的数据进行修改,阅读者也更加方便理解。
3 指针常量
关于指针常量,形式为int* const p;表示p是一个常量,但它是一个指针。所以p是一个指针,但它指向的地址不能修改。
// p5 是一个 指针常量, 既然是常量那么指针指向的对象唯一,但数据可以修改(类似引用)。
int m5 = 5;
int* const p5; // 给p5分配空间,但是不给他赋初值,所以指针p5指向一个随机地址
//*p5 = m5; // when running, segment default //对随机地址赋值,可能造成栈溢出
//p5 = &m5; // error // p5是一个常量,是不可以修改值的
printf("&p5: %p, p5: %p\n", &p5, p5);
4 code demo
上面为关于指针常量和常量指针的介绍,下面提供一个可运行的demo。大家可以自己测试一把:)
#include <stdio.h>
int main(){
// p0 是一个可指向任何类型的指针
void *p0;
int m0 = 0;
p0 = &m0;
printf("%d\n", *(int *)p0);
// p1 是一个可指向 int型的指针
int *p1;
int m1 = 1;
p1 = &m1;
printf("%d\n", *p1);
// p2 p3 是一个 常量指针 指向常量的指针。
// p2 是一个可指向任何类型的指针,被const修饰, 不可以修改指向的对象值,但是可以指向其他的对象。
const void *p2;
int m2 = 2;
p2 = &m2;
//*p2 = 3; //error
printf("%d\n", *(int*)(p2));
// p3 是一个指向int形的指针,被const修饰,不可以修改指向的对象值,但是可以指向别处
const int *p3;
int m3 = 3;
p3 = &m3;
//*p3 = m3; //error
printf("%d\n", *p3);
// int const *p === const int *p 等价,不可以修改指向的值,但可以指向不同对象
int const *p4;
int m4 = 4;
p4 = &m4;
//*p4 = m4;
printf("%d\n", *p4);
// p5 p6 是一个 指针常量, 既然是常量那么指针指向的对象唯一,但数据可以修改(类似引用)。
int m5 = 5;
int* const p5; // 给p5分配空间,但是不给他赋初值,所以指针p5指向一个随机地址
//*p5 = m5; // when running, segment default //对随机地址赋值,对造成栈溢出
//p5 = &m5; // error // p5是一个常量,是不可以修改值的
printf("&p5: %p, p5: %p\n", &p5, p5);
int m6 = 6;
int* const p6 = &m6;// 给p6分配空间,并且把m6的地址给他
*p6 = 1;
printf("%d\n", *p6); // ok
printf("&p6: %p, p6: %p, *p6: %d &m6: %p, m6: %d\n", &p6, p6, *p6, &m6, m6);
return 0;
}
5 reference
http://www.cnblogs.com/lizhenghn/p/3630405.html
https://blog.csdn.net/stpeace/article/details/45349757