• [C语言]类型限定词const解析


        作为C90增加的一个受限类型关键字,const赋予了它修饰的变量一个新属性——不变性,如果一个变量声明中带有关键字const,则无法通过赋值、增减运算来修改该变量的值。

    一、指针与const结合

        const与指针的结合较为复杂,因为我们需要把'让指针本身成为const'和'让指针指向的值成为const'区分开来。

    1.1 int const *p

            该声明表明我们声明了一个指针p,const在*左边,代表整个'*p'为不可修改的,也即p指向的值不可变。

    1. int a = 2;  
    2. int b = 10;  
    3.     
    4. const int *p = &a;  
    5.     
    6. printf("%x %d ",p,*p);  
    7. *p = 4;  
    8. printf("%x %d ",p,*p);  

            尝试修改指针p指向的值,编译后报错:[Error] assignment of read-only location '*p',p指向的位置为只读。

            修改一下a的值,看运行结果。

            没有报错,a的值被成功修改。

            再试一下,修改p的值:

    1.     int a = 2;  
    2.     int b = 10;  
    3.         
    4.     const int *p = &a;  
    5.     
    6.     printf("%x %d ",p,*p);  
    7. //  *p = 4;     //[Error] assignment of read-only location '*p'   
    8.     p = &b;   
    9.     printf("%x %d ",p,*p);  

            运行成功,由结果能看出,const的只读限制只对*p起作用,而p、p指向的对象的操作(a)都可读可写。

            再看一个,将有const的指针赋值给没有const的指针:

    1. int a = 2;  
    2. int b = 10;  
    3.     
    4. const int *p = &a;  
    5.     
    6. printf("%x %d ",p,*p);  
    7. int *p1 = &a;  
    8. printf("%x %d ",p1,*p1);  
    9. p1 = p;  

            被const修饰的p与没有被修饰的p1值相同,指向位置的值也相同。不过在第九行'p1 = p;',弹出警告,继续运行:[Warning] assignment discards 'const' qualifier from pointer target type

        1.2 int * const p

            const在*右边,代表指针p不可修改,也即p总是指向同一个地址。

            先修改个地址试一试。

    1. int a = 2;  
    2. int b = 10;  
    3.     
    4. int * const p2 = &a;   
    5. printf("%x %d ",p2,*p2);  
    6. p2 = &b;      

            第六行报错:[Error] assignment of read-only variable 'p2',p2为只读变量。

            再折腾折腾,直接修改它指向的值,引用对象的值试试。

            p2指向的地址都没变,只要不修改地址,其余的操作都可行。

        1.3 const int * const p

            第一个const表示p指向的值不可变,第二个const表示p本身不可变。也即p必须指向同一个位置,且所指位置存储的值也不可改变。

    1.     int a = 2;  
    2.     int b = 10;  
    3.         
    4.     const int * const p3 = &a;  
    5.     printf("%x %d ",p3,*p3);  
    6.         
    7.     a = 3;  
    8.     printf("%x %d ",p3,*p3);  
    9.         
    10. //[Error] assignment of read-only variable '*p3'  
    11. //  p3 = &b;  
    12.     printf("%x %d ",p3,*p3);  
    13.         
    14. //[Error] assignment of read-only location '*p3'  
    15. //  *p3 = 1;      
    16.     printf("%x %d ",p3,*p3);  

        1.4 总结

            当const与指针一同出现时,位于*左边的const使得数据成为常量,位于*const右边的const使得指针自身成为常量。更直白点来说就是:修饰谁,谁的内容就不可变,其余的都可变。

    二、const与全局变量

        由于程序的任何部分都可以修改全局变量的之,因此使用全局变量是一种很冒险的写法。但当我们用上了const后,这个问题就解决了。

        2.1 extern

            在一个工程中,如果我们在一个.c文件中声明了一个全局常量,在该工程其他文件中,对该全局常量的引用就需要使用关键字'extern'。

    1. /* file1.c---存放有全局常量的文件*/  
    2. const int num = 100;  
    3.     
    4. /* file2.c---需要引用全集常量的文件*/  
    5. extern const int num;  

        2.2 include与static

            通过将全局声明放入头文件.h中,可以不必再纠结在哪个文件定义了声明、哪个文件引用了声明。不过需要注意的是,在声明时,const前必须加上static关键字,否则每一个引用该.h的文件都会得到该数据的一个副本,从而导致不同文件间的数据交流出问题。

    1. /*constant.h*/  
    2. static const int num = 100;  

            使用头文件的缺点在于每一次引用.h都复制了数据,当.h中含有大量的数据时,就会引发新的问题了。

            

  • 相关阅读:
    JQuery制作网页——第五章 初识 jQuery
    JQuery制作网页—— 第四章JavaScript对象及初识面向对象
    JQuery制作网页—— 第三章 JavaScript操作DOM对象
    JQuery制作网页—— 第二章 JavaScript操作BOM对象
    JQuery制作网页—— 第一章 JavaScript基础
    JAVA / MySql 编程——第八章 DAO 模式
    JAVA / MySql 编程——第七章 JDBC
    JAVA / MySql 编程——第六章 Mysql 创建账户的相关命令
    JAVA / MySql 编程——第五章 事务、视图、索引、备份和恢复
    JAVA / MySql 编程—— 第四章 高级查询(二)
  • 原文地址:https://www.cnblogs.com/magicxyx/p/10158856.html
Copyright © 2020-2023  润新知