深入理解C之关键字

        由于最近一段时间一直在忙于WEB的前端开发,很久都没有写过C方面的程序,感觉很陌生了一样,真的是一天不练,都被拉到千里之外,趁现在正好手上有一个关于C方面的项目,特地的总结了一下C语言关键字的使用及注意事项。


                           C语言标准定义的32个关键字

auto声明自动变量,缺省时编译器一般默认为auto
int声明整理变量
double声明双精度变量
long声明长整型变量
char声明字符型变量
float声明单精度浮点变量
short声明短整型变量
signed声明有符号类型变量
unsigned声明无符号类型变量
struct声明结构体变量
union声明联合数据类型
enum声明枚举类型
static声明静态变量
switch用于开关语句
case开关语句分支
default开关语句的其它分支
break跳出当前循环
register声明寄存器变量
const声明只读变量
volatile说明变量在程序执行中可被隐含地改变
typedef用以给数据类型取别名
extern声明变量是在其他文件中声明(也可看作引用变量)
return子程序返回语句(可以带参数,也可以不带参数)
void声明函数无返回值或无参数、声明空类型指针
continue结束当前循环,开始下一轮循环
do循环语句的循环条件
while循环语句的循环条件
if条件语句
else条件语句否定分支
for一种循环语句(可意会不可言传)
goto无条件跳转语句
sizeof计算对象所占内存空间大小








































      下面挑选一些比较重要,容易将用法和概念混淆的关键字进行总结,以下内容是本人查找资料进行整理的。

一、Const

      const从字面是恒定不变的意思,也翻译成常量和常数,可能正因为这一点,很多人都认为被const修饰的值是常量,这不精确,精确来说应该是只读变量,其值在编译时不能被使用。

      1、Const作用

             (1)可以定义定义const常量:const int MAX = 100;
             (2)便于进行类型检查:const常量有数据类型,而宏常量没有数据类型,

             (3)可以保护被修饰的东西:防止意外的修改,增强程序的健壮性。

             (4)可以很方便的进行参数的调整:同宏定义一样,可以做到不变则已,一变都变。

             (5)提高了效率:编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中。

             示例程序:

             #define   M      3                     //宏常量

             const  int  N = 5;                   //此时并未将N放入内存中

             .......

             int  i = N;                                //此时为N分配内存,以后不再分配

             int  I = M;                               //预编译期间进行宏替换,分配内存

             int  j = N;                                //没有内存分配

             int  J = M;                               //再进行宏替换,又一次分配内存

       2、Const的变量和指针使用

         (1)定义常量:const修饰类型的变量value是不可变的,以下两种定义形式在本质上是一样的。

            int const ValueName = value;

            const int ValueName = value;

        (2)指针使用const

            a. 指针本身是常量不可变

                     char* const pContent;

           b. 指针所指向的内容是常量不可变

                     char const* pContent;

           c. 两者都不可变

                     const char* const pContent;

           d. 区别方法

                   在*中间画一条线,如const在*左边,则const修饰指向的变量,如cosnt在*右边,const修饰指针本身。

      3、函数中使用Const

       (1)const修饰函数参数     

           a. 传递过来的参数在函数内不可变(无意义,因为Var本身就是形参)

                      void function(const int Var);

          b. 参数指针所指内容为常量不可变

                      void function(const char* Var);

          c. 参数指针本身不可变(无意义,因为char * Var也是形参)

                       void function(char* const Var);

          d. 参数为引用,为了增加效率同时防止修改,参数不可变--C++特性

                       void function(const Class & Var);

       (2)const修饰函数返回值

           const修饰函数返回值其实用的并不是很多,它的含义和const修饰普通变量以及指针的含义基本相同。

           a.  const int fun1() ;          //这个其实无意义,因为参数返回本身就是赋值

           b.  const int * fun2();        //调用时使用const int *pValue = fun2();

                                                       //我们可以把fun2()看成一个变量,即指针内容不可变

           c.  int * const fun3();        //调用时使用int* const pValue = fun3();

                                                       //我们可以把fun3()看成一个变量,即指针本身不可变

二、Static

        从字面意思是静止的、不变的,下面主要从作用域、存储域方面进行讲解。

        1、修饰变量

            修饰变量又分为修饰局部变量和修饰全局变量。

            (1)修饰局部变量

                作用域:只限在本文件使用(又称内部变量),外部文件不能使用,准确的说,作用域是从定义之处开始,到文件结束,定义之前的代码不能使用它。

                存储域:存储在静态区,同时在所处模块初次运行时进行初始化工作,且只初始化一次。

            (2)修饰全局变量

                作用域:只限在本文件使用,外部文件不能使用。

                存储域:存储在静态区,如果不赋初值,编译期会自动赋初值0或空字符。

           (3)普通变量

                作用域:局部变量生存周期在模块执行时,执行结束就被立刻释放,全局变量在整个文件和外部文件(使用extern声明)都可使用。

                存储域:局部变量存储在栈区,全局变量存储在静态区。

        示例程序一:             

        #include <stdio.h>

        void staticAddVal()
        {
            static int a;
            printf("a=%d ",a);
            a ++;  
        }

        int main()
        {
            staticAddVal();   <span style="color:#009900;">//第一次调用输出a=0;</span>
            staticAddVal();   <span style="color:#009900;">//第二次调用记忆了第一次退出的值,输出a=1</span>
            return 0;
        }

        示例程序二:                            

        //file1.c
        int varA = 1;
        static int varB;
 
        void funA(){} 

         .....

        //file2.c
        extern int varA;     <span style="color:#009900;">//使用file1.cpp中定义的全局变量</span>
        extern int varB;     <span style="color:#009900;">//错误!varB是static类型,无法在其它文件中使用</span>
   
         .....

        int main()
        {
           ....
        }

        2、修饰函数

              修饰函数使得函数成为静态函数,但此处的"static"的含义不是指存储方式,而是指对函数的作用域仅局限于本文件(又称内部函数),利用这一特性可以在不同的文件中定义同名函数,而不必担心命名冲突。

        示例程序三:           

        //file1.c
        void funA()
        {
            ....
        }

        static void funB()
        {
            ....
        }

        //file2.c
        extern void funA();   <span style="color:#009900;">//使用file1.c中定义的函数</span>
        extern void funB();   <span style="color:#009900;">//错误!无法使用file1.c文件中的static函数</span>
 
         .....

        int main()
        {
            .....
        }
三、Extern

        修饰符extern用在变量或者函数的声明前,用来说明此变量/函数是在别处定义过的,要在本文件中引用。

        注:定义的全局变量或函数默认的是extern,具有外连性。

       1、extern修饰变量/函数

       示例程序一:        

       //file1.c   
       int iNum = 10;
       int iVar = 9.9;

       void funA(void)
       {
          .....
       }
       static void funB(void)
       {
          .....
       }

       //file2.c
       extern int iNum;         <span style="color:#009900;">//使用file1.c中的变量iNum</span><span style="color:#006600;"> </span>
       extern double iVar;      <span style="color:#009900;">//错误!类型不一样</span>
       extern void funA(void);  <span style="color:#009900;">//调用file1.c中的函数funA</span>
       extern void funB(void);  <span style="color:#009900;">//错误!static修饰的函数具有隐藏性,不可外用</span>

        .....
       
       int main()
       {
          ...
       }

       2、extern "C"的使用

              在C++环境下使用C函数时,常常会出现编译器无法找到obj模块中的C函数定义,从而导致链接失败的情况。

             示例程序二:

       #ifdef __cplusplus
       extern "C" {
       #endif

       /*...*/
 
       #ifdef __cplusplus
       }
       #endif
四、Volatile

        volatile是易变的、不稳定的意思,遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。

        示例程序一:

               int i  =  10;
               int j  =  i;      //①语句
               int k =  i;      //②语句

        此时编译器对代码进行优化,这是因为①②语句中,i没有被赋值,这是编译器认为i的值没有发生改变,所以在①语句时从内存中取出i的值赋给j之后,这个值并没有被丢掉,而是在②语句时继续赋值给k。

        示例程序二:

               volatile int i  =  10;
               int j  =  i;      //①语句
               int k =  i;      //②语句

       volatile关键字告诉编译器,i随时可能发生变化的,每次使用他的时候必须从内存中取出i的值,因而编译器生存的汇编代码会重新从i的地址处读取数据放在k中。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值