C语言const修饰符探秘
来源:互联网 发布:java旅游管理项目描述 编辑:程序博客网 时间:2024/05/17 04:13
前言
C语言是我接触的第一门程序设计语言,当时还很傻很天真,后来迅速被各种高级语言洗脑,但是不得不说,C的地位真的无可撼动。
const修饰符在C语言中很常用,但是最近读代码的时候常常搞不清楚,搜索了一番,做个总结。
整体认知
const是常量修饰符,代码中设法阻止变量被改变,这个时候可以使用const关键字。必须在声明const变量就初始化,因此,类似与这样的声明是错误的:
const int i;i = 8;
编译器会报:error: assignment of read-only variable ‘i’。
我们必须要这样:
const int i = 8;
const修饰符的典型作用
- 最基本的,保护被修饰的作用,防止以外修改
- 编译器通常不为const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储和读取内存的操作,效率很高
- 使程序中的错误在编译的时候就被报出(因为2)。
下面会一一举例说明。
const修饰符的修饰对象探秘
修饰普通变量
const int i = 8;int const i = 8;
上面两者是等价的,都是声明了一个值为5的常量。
修饰指针
const int *p;int const *p;
上面两个是等价的,都声明了一个const int类型的指针,也就是说,程序里面不能改变*p的值,但是可以改变p的值(即可以改变指针的指向)。
int * const p = &n;
这个是声明了一个const的指针,const是修饰指针的。也即p的值不允许改变(指针就一定得指向n那块内存,不能改变p的指向),但是*p的值可以改变。
小技巧
- const在*的左侧,const修饰指针所指的变量
- const在*的右侧,const修饰指针本身
带const修饰的函数形参
首先要明确一点,非指针参数(值传递)传给函数的是参数的一份拷贝,本身就不会改变参数的值,所以加上const是没有意义的,例如:
#include <stdio.h>void add(const int a){ a = a + 1;}int main(){ int temp = 34; add(temp); printf("%d",temp); return 0;}
虽然编译过不去,但是,就算不加const,在函数体中成功尝试修改了a,但是在本例中temp的值也是不变的,因为函数中修改的是a的一个拷贝(值传递)。
先看这个函数:
void foo(const int * p){ *p += 1;}
编译时就会报错,因为我们试图修改一个常量的值。
带const的形参是不允许在函数体内修改其值的(只读)。
不过一旦这样写就没辙了:
void foo(const int * p){ int *r = p; *r += 1;}
虽然编译器编译时会告诉你:warning: initialization discards qualifiers from pointer target type,说你赋值丢了一个属性修饰符,但是运行时还是可以改变p所指向内存的值。
再看这样一个例子:
void foo(int *const p1) { int a = 1; p1 = &a; }
显然编译不过去。这样做本来是想传进来一个const的指针,但实际上,这样是没有意义的。指针作为参数时也是传进去一个指针的拷贝。所以即使不加const,函数体中也是修改的这个“指针的拷贝”。这个函数实际上和本小节开头的例子是没区别的(但是这个指针的拷贝所指向的内容可是和被拷贝的东西是一样的)。
可以用下面的图说明:
和这个是类似的:
- C语言const修饰符探秘
- c语言const修饰符问题
- C语言之const修饰符
- 黑马程序员-------C语言----const修饰符
- C语言之const修饰符
- C语言const的修饰
- C修饰符const
- C语言的那些小秘密之const修饰符
- const修饰符在c语言编程中的注意事项
- C语言的那些小秘密之const修饰符
- C语言的那些小秘密之const修饰符
- C语言的那些小秘密之【const修饰符】
- C语言的那些小秘密之const修饰符
- 【C语言】函数参数中的const修饰符
- C语言类型限定修饰符(十八)const、(*)、
- c语言的指针、数组和常量修饰符const
- c语言中去除const修饰
- C语言--const修饰指针解析
- Linux下Qt 安装及环境变量设置(Ubuntu 10.04)
- hdu1098:Ignatius's puzzle
- 排序算法---选择排序
- ORACLE_CMD命令(最全的)
- 一路向北,是否可以不回头?
- C语言const修饰符探秘
- php知识盲点
- 最大子段和问题,最大子矩阵和问题,最大m子段和问题
- Oracle 11G在RHEL 5.3上的安装文档
- D-separation 2013/4/21 0:59
- poj 1611
- 黑马程序员----JAVA基础集合框架_迭代器
- 16周规划17周总结
- cygwin中的环境变量设置