一、const用途

const是一个C语言的关键字,它限定一个变量不允许被改变。

1、const与基本类型

const char m;//限定m不可变。

2、const与指针

1)、const在*前面

const char *p; //*p是const,

p可变

char const * p;//

*p是const,

p可变

2)、const在*后面

char * const

p;//p是const,*p可变

3)、const在*前面及后面

char const* const p;//

p和*p都是const

const char* const

p;//p和*pt都是const

(1)const在*前,即表示*p不能变,但p能变;const在*后面,就表示p不能变,*p能变。

(2)const与char前后顺序并不重要

注意:const (char *)

p;和(char *) const

p;这是错误的,括号会被当成强制类型转换。

补充:

typedef char *char_pointer;

char_pointer const p4=&a;

p4=&a;//error

*p4='c';

这里,char_pointer表示类型char *,p4是一个const常量,不能改变,但*p4可以改变;

注意,

const char_pointer

p4=&a;相当于

char_pointer const

p4=&a;

p4不能修改,*p4能修改。

不能把char_pointer直接替换成char *,否则的话就变为:

const char *

p4=&a;

那样的话,就是*p不能变,p可以变了。

3、用作函数形参:

函数的某个参量如果声明为const,就表示在该函数内部不能对该参数进行修改。这个参数如果是非地址变量,就没有必要加const,因为这样的变量本身就是不可改变的,只有参数是地址(数组名和指针)时,加const才有意义。

二、const限制变量使用规则

1、常量或非常量数据的地址都可以赋给指向常量的指针;

2、只有非常量数据的地址才能赋给普通指针。

其实很好理解,如果我们允许一个普通指针指向一个常量数据,那通过指针就可以修改不允许修改的常量。

引申:

1)如果函数的某个参数(指针)是const的,则可以接受指向常量的指针以及普通指针作为实参;

2)如果函数的某个参数(指针)不是const的,则只能接受普通指针作为实参;

示例1:const变量

& 字符串常量

请问下面的代码有什么问题?

char *p = "i'm hungry!";

p[0]= 'I';

答案与分析:

上面的代码可能会造成内存的非法写操作。分析如下, "i'm

hungry"实质上是字符串常量,而常量往往被编译器放在只读的内存区,不可写。p初始指向这个只读的内存区,而p[0] = 'I'则企图去写这个地方,编译器当然不会答应。

示例二:const限制变量使用规则

char string[4] = "abc";

const char arr[4]= "def";

char * const p1;

char * const p2 = string;

char * const p3 = arr; //warning

const char * p4 = string;

const char * p5 = arr;

char * p6=string;

char * p7=arr; //warning

*p1='s';

*(p1+1)='t';

*p2='s';

*(p2+1)='t';

*p3='s';

*(p3+1)='t';

*p4='s';

//error

*(p4+1)='t';//error

*p5='s';//error

*(p5+1)='t';//error

*p6='s';

*(p6+1)='t';

*p7='s';

*(p7+1)='t';

程序说明:

arr是一个指向常量数组的指针;string是一个普通指针。

1)char * const

p1;

没有错误,但不赞成这么做。

声明一个变量时,编译器会随机为其赋一个值,因为p1是指针,所以随机指定一个内存地址赋给p1,且以后p1也不能指向其它地址。但这个地址可能是不能占用的。

后面的赋值语句:

*p1='s';

*(p1+1)='t';

可以执行,但是是把这两个字符放在这个随机指定的位置,可能覆盖重要数据。

2)char * const p3

= arr; //warning

请注意,p3不是指向常量的指针,这个const只是说p3不能改变,但p3所指向的地址存的值,可以通过*p3改变。但arr被声明为const,也就是说其包含的变量是不能改变的。将arr赋给*p3这就产生了矛盾。

这样我们可以用*p3去修改一个不允许修改的值。

为了更清楚地说明这点,再看一例:

const int i=5;

printf("i1=%d, ",i);

int *p=&i;

*p=2;

printf("i2=%d\n",i);

输出i1=5, i2=2

可以看到,i本来是不可改变的值,但通过*p却改变了。

3)char * p7=arr; //warning

与2)道理一样。

4)*p4=;

及*(p4+1)='t'; 两句都错误

前一句简单,因为p4是指向常量的指针,所以不能对*p4赋值。

我们要特别注意后一句,即,对于指向常量的指针,不仅不能对*p4赋值,也不能对任何*(p4+m)赋值,不管这个m是多少。

另外还需要特别注意的是,p4指向的string不是const的,我们虽然不能通过*(p4+m)的方式修改string的内容,但我们可以用string[m]=’s’的方式修改。

5)*p5='s';及

*(p5+1)='t';两句都错

与4)一样。

重点强调:

1)指向常量的指针:const char *p;

可以指向常量,也可以指向普通变量。不能用通过*p修改所指向的变量,但不代表该变量不能修改。

2)普通指针char *p;以及指针char * const p;

如果指向常量,虽然编译可能会通过,但会出现警告,因为它可以通过*(p+m)的方式修改一个不允许修改的常量。

最后再强调一点,“const常变量只能用于允许使用变量的地方”。

c语言const字符串,C语言之正确使用const相关推荐

  1. c语言怎么用scanf输入字母,c语言输入字符串(c语言怎么用scanf输入字符串)

    但是实际操作发现我的字符串无论输入的多长多短,都是输入的什么输出的就. 在C语言中,输入输出字符串有以下两种方式:1 用scanf/printf输入输出.scanf/printf是C语言的格式化输入输 ...

  2. c语言如何让字符串变成空字符,C语言初始化字符串 c语言 如何将已赋值的字符串初始化为空?...

    C语言数组字符串初始化问题恋爱语录:能牵手的时候,请别肩并肩,能拥抱的时候,请别手牵手,能相爱的时候,请别说分开:拥有了爱情,请别去碰暧昧 字符数组的定义与初始化字符数组的初始化,最容易理解的方式就是 ...

  3. C语言 char 字符串 - C语言零基础入门教程

    目录 一.char 字符串简介 二.字符和字符串区别 1.取值范围相同 2.字符串由多个字符构成 3.字符串和字符使用 printf 函数 三.char 字符串遍历 四.猜你喜欢 零基础 C/C++ ...

  4. c语言输入字符串的格式不正确的是,关于c#:输入字符串的格式不正确

    我是一个新的C语言,我有一些基本的Java知识,但是我不能让这个代码正常运行. 它只是一个基本的计算器,但当我运行程序vs2008时,会出现以下错误: 我做了几乎相同的程序,但在JAVA中使用jSna ...

  5. c语言单片机字符串,C语言与单片机-5-变量输入和输出

    在学习C语言时,首先学会简单的输入和输出是必须的.sacnf( )和printf( )可以帮助我们完成基本的输入和输出.在C++中很简单,就是cin和cout.. 首先,我们计算一道简单简单的数学题: ...

  6. c语言扫描字符串,C语言字符串操作

    C语言字符串操作 C语言是一门通用计算机编程语言,在我们的日常生活中应用非常广泛,今天小编为大家搜集整理出来的有关于C语言字符串操作,希望可以帮助到大家! ①strcmp函数原型:int strcmp ...

  7. c语言格式化字符串,C语言格式化输出小结

    函数说明 在gcc编程中,我们常用到的字符格式化输出函数是printf的,实际上gcc继承了C语言处理字符具有强大功能的风格,它提供了一系列的格式化输出函数,主要存在两个库函数文件stdio.h/ s ...

  8. c语言isdigit字符串,C语言 isdigit

    isdigit是计算机应用C语言中的一个函数,主要用于检查参数c是否为阿拉伯数字0到9. 1函数信息 2判断方法 相关函数 isdigit 表头文件 #include 定义函数 int,isdigit ...

  9. C语言中如何输出字符的编码,c语言输出字符串(c语言自我介绍编码)

    如果我想要限定输出字符串的长度,应该怎么操作. 在C语言中,输入输出字符串有以下两种方式:1 用scanf/printf输入输出.scanf/printf是C语言的格式化输入输出函数,可以用于输入输出 ...

最新文章

  1. VMware排错:Number of virtual devices exceeds the maximum for a given controller
  2. 联想平板电脑win10如何取消触摸键盘按键声音
  3. PMCAFF产品经理第一课 | 「在行」价值1.5万元的强大课程体系,365天能力突围
  4. h5跳转小程序页面url_web-view h5跳转到小程序页面,无法跳转?
  5. 博士申请 | 澳大利亚悉尼科技大学招收人工智能/软件工程方向全奖博士生
  6. android jpush json,发送了正确的JPush json却报1002
  7. 《C专家编程》第二章——这不是Bug,而是语言特性
  8. python读取html中body_python批量获取html内body内容的实例
  9. 推荐实践:新一代Rank技术在阿里巴巴定向广告推荐系统中的应用与实践
  10. 2021-2025年中国传感器融合行业市场供需与战略研究报告
  11. 前端面试:如何修改overflow:scroll 滚动条的默认样式-如背景色以及宽度
  12. DBSCAN(自适应密度聚类)算法解析
  13. Thinkphp结合phpqrcode生成二维码海报代码
  14. CSAPP家庭作业答案7 8 9章
  15. 华为云查询弹性云服务器规格信息,查询规格详情和规格扩展信息列表
  16. Frank and Hall
  17. 计蒜客习题:猴子打字
  18. java面试详解-总有你能碰得到的
  19. uniapp H5 实现地图选址功能
  20. vertical-align 与 line-height 傻傻分不清??

热门文章

  1. P8837 [传智杯 #3 决赛] 商店
  2. 聚焦热点 | ISC 2022软件供应链安全治理与运营论坛圆满落幕
  3. python xpath定位 嵌套标签_python爬虫中使用Xpath方法定位a标签中所有的子标签的方法...
  4. GPT究竟是谁的机会?
  5. 野蛮时代一直显示无法连接服务器,Euro Truck Evolution (Simulator)无法连接服务器是什么原因...
  6. c#.net 获取时间日期年月日时分秒格式(转)
  7. 演示:MyBatis Plus 写业务代码,确实一把梭!
  8. 破案现场:记一次压测异常排查--Redisson锁失效的场景
  9. RSA对数据进行加签和验签
  10. 手机网站、移动网站、WAP网站建站 实例参考 经验分享