C中的关键字
原文地址:http://blog.chinaunix.net/u1/37549/showart_465022.html
一、const修饰符
const意味着"只读"。区别如下代码的功能非常重要,也是老生长谈,如果你还不知道它们的区别,而且已经在程序界摸爬滚打多年,那只能说这是一个悲哀:
const int a; int const a; const int *a; int * const a; int const * a const; |
Const修饰符在C语言中是一个比较新的描述符,意即其所修饰的对象为常量。
说明:
1、必须初始化
const int i=5; //合法
const int j; //非法,导致编译错误
{const int j;j=5;} //非法
2、可以通过函数进行初始化
int value();
const int i=value();
3、限定符声明变量只能被读,即其值不可以修改
const int i=5;
int j=0;
i=j; //非法,导致编译错误
J=i; //合法
4、可以在另一个连接文件中引用const常量
extern const int i; //合法
extern const int j=10; //非法,常量不可以被再次赋值
5、数值常量和指针常量
const int p1 //p1是常量,p1的值不能被修改
const int *p2 //指针p2所指的内容是常量,不能被修改,当p的指向可以被修改。
Const int * const p3 //指针p3是常量,所指内容也是常量
二、Static修饰符
1、用static声明局部变量
该变量为静态局部变量,即该局部变量的值在函数调用结束后不消失而保留原值,即其占用的存储单元不释放,在下一次该函数用时,该变量已有值,就是上一次函数调用结束时的值.
程序例子:
int fac(int n)
{
static int f=1;
f=f*n;
return(f);
}
int main(int argc,char **argv)
{
int i;
for(i=1;i<5;i++)
{
Printf("%d!\n",i,fac(i));
}
} |
运行结果:
1!=1
2!=2
3!=6
4!=24
5!=120 |
2、用static声明外部变量
该变量为静态外部变量,该变量只限于被本文件引用,而不能被其他文件引用。
三、valatie修饰符
volatile修饰符号告诉编译程序不要对该变量所参与的操作进行某些优化。
一般来说,volatile用在如下的几个地方:
1)中断服务程序中修改的供其它程序检测的变量需要加volatile;
2)多任务环境下各任务间贡享的标志应该加volatile;
3)存储器映射的硬件寄存器通常也要加volatile说明,因为每次都它的读写都可能有不同意义;
程序例子:
time_t time_addition(volatile const struct timer *t,int a)
{
int n;
int x=0;
volatile time_t then;
then=t->value;
for(n=0;n<1000;n++)
{
x=x+a;
}
return t->value-then;
} |
C语言编译器会对用户书写的代码进行优化,譬如如下代码:
int a,b,c; a = inWord(0x100); /*读取I/O空间0x100端口的内容存入a变量*/ b = a; a = inWord (0x100); /*再次读取I/O空间0x100端口的内容存入a变量*/ c = a; |
很可能被编译器优化为:
int a,b,c; a = inWord(0x100); /*读取I/O空间0x100端口的内容存入a变量*/ b = a; c = a; |
但是这样的优化结果可能导致错误,如果I/O空间0x100端口的内容在执行第一次读操作后被其它程序写入新值,则其实第2次读操作读出的内容与第一次不同,b和c的值应该不同。在变量a的定义前加上volatile关键字可以防止编译器的类似优化,正确的做法是:
volatile变量可能用于如下几种情况:
(1) 并行设备的硬件寄存器(如:状态寄存器,例中的代码属于此类);
(2) 一个中断服务子程序中会访问到的非自动变量(也就是全局变量);
(3) 多线程应用中被几个任务共享的变量。
CPU字长与存储器位宽不一致处理
在背景篇中提到,本文特意选择了一个与CPU字长不一致的存储芯片,就是为了进行本节的讨论,解决CPU字长与存储器位宽不一致的情况。80186的字长为16,而NVRAM的位宽为8,在这种情况下,我们需要为NVRAM提供读写字节、字的接口,如下:
typedef unsigned char BYTE;
typedef unsigned int WORD;
/* 函数功能:读NVRAM中字节
* 参数:wOffset,读取位置相对NVRAM基地址的偏移
* 返回:读取到的字节值
*/
extern BYTE ReadByteNVRAM(WORD wOffset)
{
LPBYTE lpAddr = (BYTE*)(NVRAM + wOffset * 2); /* 为什么偏移要×2? */
return *lpAddr;
}
/* 函数功能:读NVRAM中字
* 参数:wOffset,读取位置相对NVRAM基地址的偏移
* 返回:读取到的字
*/
extern WORD ReadWordNVRAM(WORD wOffset)
{
WORD wTmp = 0;
LPBYTE lpAddr;
/* 读取高位字节 */
lpAddr = (BYTE*)(NVRAM + wOffset * 2); /* 为什么偏移要×2? */
wTmp += (*lpAddr)*256;
/* 读取低位字节 */
lpAddr = (BYTE*)(NVRAM + (wOffset +1) * 2); /* 为什么偏移要×2? */
wTmp += *lpAddr;
return wTmp;
}
/* 函数功能:向NVRAM中写一个字节
*参数:wOffset,写入位置相对NVRAM基地址的偏移
* byData,欲写入的字节
*/
extern void WriteByteNVRAM(WORD wOffset, BYTE byData)
/* 函数功能:向NVRAM中写一个字 */
*参数:wOffset,写入位置相对NVRAM基地址的偏移
* wData,欲写入的字
*/
extern void WriteWordNVRAM(WORD wOffset, WORD wData)
阅读(738) | 评论(0) | 转发(0) |