首页 > 代码库 > 存储类别和类型限定词

存储类别和类型限定词

 

存储类别

 

五种类别:自动,寄存器,具有代码块作用域的静态,具有外部链接的静态,具有内部链接的静态。

 

链接:外部链接:文件作用域的变量。内部链接:static修饰的具有文件作用域的变量有内部链接),

 

空链接:具有代码块作用域或者函数原型作用域的变量具有空链接

 

<1>局部变量:函数内定义,函数内可见;

 

       全局变量(外部变量):函数外定义,本源文件内可见。一般全局变量第一个字母大写
<2>动态存储方式:auto声明(动态变量) register(寄存器)   -----------------函数调用结束后存储空间释放
       静态存储方式:static声明的局部变量    (extern声明的)外部变量--------------在程序整个运行期间都不释放
<3>用static声明局部变量:函数调用结束后不丢失而保留原值。
<4>register变量:只有局部动态变量和形参可以作为寄存器变量,快速存储时使用。register long i;寄存器变量的地址无法获得;如果有多余的寄存器,将i优先放到寄存器中,加快执行速度。
<5>用extern声明外部变量:
  在多个文件内声明外部变量:在a.c文件中定义具有外部链接的静态变量Num,而在另一文件中用extern对Num作“外部变量声明(extern Num)。该声明常被放在定义该变量的C文件的配套的头文件中。a.c文件中的外部函数也可以声明来提高程序的可读性。
<6>用static声明外部变量:只限于被本文件使用,而不能被其他文件使用。

 

 

类型限定词

1,const

http://blog.csdn.net/welcome_ck/article/details/227964

<1>对全局数据使用const,保护数据,可以有const变量,数组和结构。

  如:const int a=2;   int const a=2;

  文件之间共享const数据时:

可以在其他文件中用extern进行声明,extern const double PI,(一般放在与定义该常量的.c文件对应的.h文件中);

将常量定义在头文件中,必须使用静态声明:static const double PI = 3.14159。

<2>修饰常对象
      常对象是指对象常量,定义格式如下:
  class A;
       const A a;
         A const a;
      定义常对象时,同样要进行初始化,并且该对象不能再被更新,修饰符const可以放在类名后面,也可以放在类名前面。 
<3>修饰常指针
const int *p=date; 或者 int const*p=date;

  指向常量的指针不能通过指针修改数值(常用作函数参量) *p=1;(不允许)  p[1]=2;(不允许) date[0]=1(允许):  

int * const p=date; p必须总是指向同一个地址,但所指向的值可变。

const int * const p=date;p必须总指向同一位置,所指位置存储的值也不能改变。

     可以将常量或非常量的地址赋给指向常量的指针;不能把常量数据的地址(或const int *p1)赋给普通指针,因为可能通过新的指针改变const数据。

<4>修饰常引用
        使用const修饰符也可以说明引用,被说明的引用为常引用,该引用所引用的对象不能被更新。其定义格式如下:
       const double & v;
<5>修饰函数的常参数
        const修饰符也可以修饰函数的传递参数,格式如下:
        void Fun(const int Var);  void fun(const STUD *student);
        告诉编译器Var在函数体中的无法改变,从而防止了使用者的一些无意的或错误的修改。     
<6>修饰类的成员函数:
        const修饰符也可以修饰类的成员函数,格式如下:
            class ClassName 
     {
             public:
                  int Fun() const;
                    .....
             };
        这样,在调用函数Fun时就不能修改类里面的数据 
    另外,还要注意,常量必须初始化!

 

2,volatile

http://www.cnblogs.com/chio/archive/2007/11/24/970632.html

<1>volatile 变量是随时可能发生变化的,与volatile变量有关的运算,不要进行编译优化,以免出错。

<2>表示用volatile定义的变量会在程序外被改变,每次都必须从内存中读取,而不能把他放在cache或寄存器中重复使用。

volatile变量的例子:

1) 并行设备的硬件寄存器(如:状态寄存器) 
2) 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables) 
3) 多线程应用中被几个任务共享的变量 

说明:

<1>一个参数可以const和volatile

如:只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它

<2>一个指针可以是volatile 

不常见,如:当一个中服务子程序修该一个指向一个buffer的指针时。 

<3> 

volatile char a;   
        a=0; 
       while(!a){ 
//do some things;   
       }   
       doother(); 
   如果没有 volatile doother()不会被执行

 

3,restrict

只可用于修饰指针,并且该指针是访问一个数据对象唯一且初始的方式。

作用:

<1>告诉编译器,可以自由做一些有关优化的假定(这个不用关心)。

<2>告诉程序员使用满足restrict要求的参数。一般,编译器无法检查你是否遵循了这一限制。

C99函数:把s2位置的n个字节复制到s1位置:

void *memcpy(void * restrict s1, const void *restrict s2, size_t n); 

//表明用户在使用这个函数时,s1,s2是相应数据的唯一访问方式,即要保证s1和s2所指向的n字节的空间没有重复。

void *memmove(void *s1, const void *s2, size_t n);

//允许重叠,该函数考虑到了数据重叠的情况,在复制数据时会避免在使用数据前就覆盖了数据。

 

随机函数:

<stdlib.h>

rand()  产生0~RAND_MAX范围内的整数;roll = rand()%6+1; roll为1~6之间的整数;使用该函数,每次重新执行时得到的随机数是一样的。

#include<time.h>

 srand((unsigned int)time(0));  //初始化种子

time()函数可以返回系统时间,单位有系统决定,返回值为数值类型。

存储类别和类型限定词