zoukankan      html  css  js  c++  java
  • 编程珠玑之关键字(1)--《c语言深度剖析》整理(转)

    一、最快关键字register

         关键字regiter请求编译器尽可能的将变量存在CPU的寄存器中。有几点注意的地方。

            1、register变量必须是能被CPU寄存器所接受的类型,这通常意味着register变量必须是一个单个的值,并且其长度应小于或等于整型的长度。

        但是,有些机器的寄存器也能存放浮点数。

           2、register变量可能不存放在内存中,所以不能用取址符运算符“ & ”。

           3、只有局部变量和形参可以作为register变量,全局变量不行。

           4、静态变量不能定义为register。

           总结:寄存器变量不是越多越好,当寄存器变量的个数超过寄存器的数目的时候,寄存变量也就退化为放到内存中。因此寄存器变量应用较少。

    二、static作用

           1. 修饰变量

           (1) 限定变量的作用域: (存放于文件的静态区中)

             本文件中:

             静态全局变量:作用域从变量定义开始处到文件结束(本文中在定义之前引用此变量也要加extern)

             静态局部变量:作用域限于定义的函数中

             工程文件中: 仅限本文件中,其他的文件的不能引用此变量

          (2) 生命周期:

            从程序启动直至程序结束。

            2. 修饰函数

            限定函数的作用域为本文件中,其他的文件不能引用此函数

    三、最容易混淆的关键字sizeof(本人之前一直以为sizeof是函数 惭愧)

           事实证明 sizeof是关键字,如下:

          int i=0;
           A),sizeof(int); B),sizeof(i); C),sizeof  int; D),sizeof  i;

          此处四种用法第三种是错误的 ,由此可见sizeof 是关键字

          关于sizeof的 一些用法习题:

        int *p = NULL;
       sizeof(p)——
       sizeof(*p)——
       int a[100];
       sizeof (a) ——
       sizeof(a[100])——
       sizeof(&a)——
       sizeof(&a[0])——
       int b[100];
       void fun(int b[100])
       {
            sizeof(b);// sizeof (b) ——
       }

     答案: 4   4   400  4   4  4  4

    四、 bool, float , 指针类型与零值的比较

       1. bool类型的值与0比较

       A), if(bTestFlag == 0); if(bTestFlag == 1);
       B), if(bTestFlag == TRUE); if(bTestFlag == FLASE);
       C), if(bTestFlag); if(!bTestFlag);

       解析:

        A :可读性比较差,不知道bTestFlag变量的类型,误以为是整形

        B:不同的编译器,true值的定义不同:Visual C++定义为1,而Visual Basic 就把TRUE 定义为-1

        C:规范 编译器中0 为false 非零为true

      2. float 与 0 比较

            float fTestVal = 0.0;
          A), if(fTestVal == 0.0); if(fTestVal != 0.0);
          B), if((fTestVal >= -EPSINON) && (fTestVal <= EPSINON)); //EPSINON 为定义好的精度。

          解析:float 在计算机存储有精度限制,与0,与具体的浮点数直接比较都是不准确的,所以B的定义较好。[0.0-EPSINON,0.0+EPSINON] 当然EPSINON范围不能过大

      3. 指针变量与0 比较

          int* p = NULL;//定义指针一定要同时初始化,指针与数组那章会详细讲解。
        A), if(p == 0); if(p != 0);
        B), if(p); if(!p);
        C) , if(NULL == p); if(NULL != p);
       解析:A  容易和int 类型的想混淆;B 容易和bool类型想混淆(可读性比较差)

    五、c语言中的空语句的写法

          1)  ;

          2) NULL;

    六、switch 关键字

           switch关键字使用注意事项:

           1) case 后面变量: 整形或字符型或者常量表达式(可以跟const类型修饰的变量,比如const int KEY = 1)

           2) 每个case 后面必须接break ,除非集中case的叠加(但case 后面绝对不可以跟continue,continue 用于循环中)

           3) deflaut 后面应用于异常情况的处理,不应将自己的case 最后一种情况介于default 之后,降低程序的容错性

    七、const 修饰只读变量

          1.  const 修饰的变量 是只读的,变量的值不可以改变,变量存在于符号表中,没有了存储与读内存的操作;

     #define M 3 //宏常量
    const int N=5; //此时并未将N 放入内存中
    ......
    int i=N; //此时为N 分配内存,以后不再分配!
    int I=M; //预编译期间进行宏替换,分配内存
    int j=N; //没有内存分配
    int J=M; //再进行宏替换,又一次分配内存!

          2.  const 修饰的变量定义的时候必须初始化

          3、const 修饰的变量是编译器变量,define 定义的变量是预编译期变量

          4、const 修饰的变量和define修饰的变量的区别

             (1)const 定义的只读变量从汇编的角度来看,只是给出了对应的内存地址,而不是象#define一样给出的是立即数

              (2)const 定义的只读变量在程序运行过程中只有一份拷贝(因为它是全局的只读变量,存放在静态区),而#define 定义的宏常量在内存中有若干个拷贝。

              (3)#define 宏是在预编译阶段进行替换,而const 修饰的只读变量是在编译的时候确定其值

              (4)#define 宏没有类型,而const 修饰的只读变量具有特定的类型。

          5. const 修饰指针

          const int *p; // p 可变,p 指向的对象不可变
          int const *p; // p 可变,p 指向的对象不可变
          int *const p; // p 不可变,p 指向的对象可变
          const int *const p; //指针p 和p 指向的对象都不可变

    八、最异变的关键字volatile

         volatile 修饰的变量表示可以被某些编译器未知的因素更改,比如操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优     化,从而可以提供对特殊地址的稳定访问;

    九、struct

          1、空结构体的大小

            struct A

            {

            }aa;

           sizeof(aa)  结果等于 1

         2. 柔性数组

          typedef struct A

          {
                int i;
                int a[];
          }aa;

          sizeof(aa) 等于 4,可见结构的体中的柔性数组的大小是0,不占结构体的空间,仿佛不是结构的体得一部分;

    十、union

         存储模式:大端模式和小端模式。
        大端模式(Big_endian):字数据的高字节存储在低地址中,而字数据的低字节则存放在高地址中。
        小端模式(Little_endian):字数据的高字节存储在高地址中,而字数据的低字节则存放在低地址中。

        union 型数据所占的空间等于其最大的成员所占的空间。对union 型的成员的存取都是相对于该联合体基地址的偏移量为0 处开始,也就是联合体的访问不论对哪个变量的存  取都是从union 的首地址位置开始

        1. 枚举类型所占空间大小

        enum Color
        {
               GREEN = 1,
               RED,
               BLUE,
               GREEN_RED = 10,
               GREEN_BLUE
        }ColorVal;

       sizeof(ColorVal)等于4

       2. 枚举与#define 宏的区别

        1),#define 宏常量是在预编译阶段进行简单替换。枚举常量则是在编译的时候确定其值。
        2),一般在编译器里,可以调试枚举常量,但是不能调试宏常量。
        3),枚举可以一次定义大量相关的常量,而#define 宏一次只能定义一个。

       3. 用函数确定系统的大小端模式

      

      1. int checkSystem( )  
      2. {  
      3.    union check  
      4.    {  
      5.      int i;  
      6.      char ch;  
      7.    } c;  
      8.    c.i = 1;  
      9.    return (c.ch ==1);  
      10.  }  
  • 相关阅读:
    实用机器学习 跟李沐学AI
    Explicitly drop temp table or let SQL Server handle it
    dotnettransformxdt and FatAntelope
    QQ拼音输入法 禁用模糊音
    (技术八卦)Java VS RoR
    Ruby on rails开发从头来(windows)(七)创建在线购物页面
    Ruby on rails开发从头来(windows)(十三)订单(Order)
    Ruby on rails开发从头来(windows)(十一)订单(Order)
    新员工自缢身亡,华为又站到了风口浪尖
    死亡汽油弹(Napalm Death)乐队的视频和来中国演出的消息
  • 原文地址:https://www.cnblogs.com/heyp/p/3798781.html
Copyright © 2011-2022 走看看