存储类别
五种类别:自动,寄存器,具有代码块作用域的静态,具有外部链接的静态,具有内部链接的静态。
链接:外部链接:文件作用域的变量。内部链接: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()函数可以返回系统时间,单位有系统决定,返回值为数值类型。