C语言中关键字const有什么含义?

           如果阅读中发现了错误,请及时告诉我,以免误人子弟。
          本文由jordanli22结合网络资源整合修改总结而成(部分原创),欢迎转载。


        const是一个C语言的关键字,它限定一个变量不允许被改变。也可以说是只可读不可写的变量。


        Cconst的用法总结起来主要分为以下两种:
 

       1.在定义变量时使用(由于const常量在定义后不能被修改,所以定义时一定要进行初始化操作)
 

    a)  最简单的用法,说明变量为一个常变量
 (在以下例子里,int const的先后顺序可以改变的,这无所谓):
         const int a=100; //a的值不允许修改了,只能是100了。
         int const b=200;//b的值不允许修改了,只能是200了。
 本质:const在谁后面谁就不可修改,const在最前面则将其后移一位即可,二者等效
 
     b)  说明指针为指向常数的指针,即指针本身的值是可以改变的:
                 const int *a=&b;//*a的值不允许改变了,但b的值可以改变,const只限制左值


  c)  说明指针本身的值不可改变,但指向的内容可改变:
                 int * const a = &b;//a的值不允许改变,只能指向b,不能指向其他值了

    d)  说明指针为指向常数的常指针,即指针本身与指针指向的内容都不可改变:
        const int * const a = &b;//*a和a指向的值都不允许改变了


     2在定义函数时使用:
 
     a) 作为参数使用,说明函数体内是不能修改该参数的:
                 void func(const int a);//a在函数func内不允许改变了
 
     b) 作为返回值使用,说明函数的返回值是不能被修改的:
                 const int func();//主要是保证返回值不允许是右值
 
           c) 在函数中使用const,情况与定义变量的情况基本一致: 

 注意:
 

    1、为什么我下面的例子一样用一个const变量来初始化数组,ANSI C的编译器会报告一个错误呢?

         const int n = 5;
                   int a[n]; 

    
答案与分析:

        1)、这个问题讨论的是常量只读变量的区别。常量肯定是只读的,例如5, “abc”,等,肯定是只读的,因为程序中根本没有地方存放它的值,当然也就不能够去修改它。而只读变量则是在内存中开辟一个地方来存放它的值,只不过这个值由编译器限定不允许被修改。C语言关键字const就是用来限定一个变量不允许被改变的修饰符(Qualifier)。上述代码中变量n被修饰为只读变量,可惜再怎么修饰也不是常量。而ANSI C规定数组定义时维度必须是常量只读变量也是不可以的。
  2)、注意:在ANSI C中,这种写法是错误的,因为数组的大小应该是个常量,而const int n,n只是一个变量(常量 != 不可变的变量,但在标准C++中,这样定义的是一个常量,这种写法是对的,下面再讨论),实际上,根据编译过程及内存分配来看,这种用法本来就应该是合理的,只是 ANSI C对数组的规定限制了它。

        3)、那么,在ANSI C 语言中用什么来定义常量呢?答案是enum类型和#define宏,这两个都可以用来定义常量。 

2const变量 字符串常量
  请问下面的代码有什么问题?
  char *p = "i'm hungry!";
  p[0]= 'I'; 
  
答案与分析:
  上面的代码可能会造成内存的非法写操作。分析如下, “i'm hungry”实质上是字符串常量,而常量往往被编译器放在只读的内存区,不可写。p初始指向这个只读的内存区,而p[0] = 'I'则企图去写这个地方,编译器当然不会答应。

3const变量 字符串常量2
    请问char a[3] = "abc" 合法吗?使用它有什么隐患? 
 
答案与分析:
  在标准C中这是合法的,但是它的生存环境非常狭小;它定义一个大小为3的数组,初始化为“abc”。注意,它没有通常的字符串终止符'\0',因此这个数组只是看起来像C语言中的字符串,实质上却不是,因此所有对字符串进行处理的函数,比如strcpyprintf等,都不能够被使用在这个假字符串上。
 

4

        constCC++中最大的不同是,在C中,const默认具有外部链接,而C++中则是内部链接。所以当你只在定义const常量的文件中使用该常量时,c++不给你的const常量分配空间,此时const int c = 0;相当于#define c 0;(在C++里面const被转化为常量)而在C中,它会给每个const 常量分配内存空间(在C里面const被定义为只读变量)
 

请看下面一个程序:

        #include <stdio.h>

        int main()

        {

               const int a = 5;

               int b[a];

               return 0;

        }

vc6.0中命名为.c文件,编译时,编译器提示错误,int b[a]这行:expected constant expression

命名为.cpp文件,则没问题。

这个问题跟编译器无关,code::blocks之所以编译能通过,其实是因为gcc默认是启用编译器扩展的,把工程的build option中的"In C mode ,supper all ISO C90 programs..........""treat as errors the warnings demonded by strict ISO ......"两项选上,去掉所有的gcc扩展,实行严格的C90标准,就不能通过编译了。 
这个问题其实跟const是所谓只读还是常量也无关,constc/c++语法中的确切意义,依然是一个不能通过被它修饰的标识符直接改变的变量。

问题的真正原因是:在c中,常量表达式必须是编译期常量,a不是编译期常量(是运行期常量),无论c90还是c99都如此,但c++没有了这个规定,对此不作限制。正因为const int ic中不是常量表达式,因此不能用于定义数组。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值