免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 846 | 回复: 0
打印 上一主题 下一主题

C中的关键字 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-02-11 09:46 |只看该作者 |倒序浏览
[color="#295200"]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
    {
        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
    {
        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 int a;
  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)
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/90602/showart_1823510.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP