Chinaunix首页 | 论坛 | 博客
  • 博客访问: 58815
  • 博文数量: 23
  • 博客积分: 270
  • 博客等级: 二等列兵
  • 技术积分: 215
  • 用 户 组: 普通用户
  • 注册时间: 2012-10-31 11:01
文章分类

全部博文(23)

文章存档

2013年(21)

2012年(2)

我的朋友

分类: C/C++

2012-12-31 19:58:56

回想几个月前刚开始学C语言,听人说C语言有多难多难被吓得一愣一愣的,后来刚学会时感觉C语言易学难精,想能用只不过几天的事情,只有三十二个关键字而已。最近回头看了一下三十二个关键字,别有一翻滋味,其实我自己也没真正看懂三十二个关键字是怎么用的。
        今天就挑几个关键字,及宏的用法,还有指针和数组名这个常见的新手绕口令来讲一讲C的基础之基础的细节。
        先讲static,const,volatile,extern,这四个关键字。面向过程和面向对象的 static有不同的用法,前者应用于普通变量和函数,不涉及类;后者主要说明static在类中的作用。限于水平暂时有限,今天只说在面向过程思想编程的static用法。在面向过程中说到static,大家的第一反应是静态,他包括静态全局变量,静态局部变量和静态函数。
全局静态变量 是显式用static修饰的全局变量,作用域是声明此变量所在的文件,其他的文件即使用extern声明也不能使用。静态局部变量保存在全局数据区,而不是保存在栈中,每次的值保持到下一次调用,直到下次赋新值。静态局部变量和全局变量的区别在于作用域不一样,静态局部落变量的作用域更加小,只在于该模块。最后还有一个静态函数,它只能在声明它的文件当中可见,不能被其它文件使用。
        再说关键字const,尽管const看起来真的有点像常数,但const意味着常数这句话是错得离谱的。最明显的就是用const修饰的变量做为数组的下标编译器会报错,做为菜鸟,暂时可以认为const代表只读的。
const int a;
int const a;
const int *a;const  修饰整型数。
int * const a; const修饰指针。
int const * a const;整型数和指针都被const修饰。
        volatile告诉编译器不可优化,哪些情况不可优化呢?常见的有
并行设备的硬件寄存器(如:状态寄存器),一个中断服务子程序中会访问到的非自动变量(Non-automatic variables),多线程应用中被几个任务共享的变量。这些量可能会因为一些原因被改变,所以每次用到这些变量时都必须重读,所以优化会出错。
     extern,
表示变量或者函数的定义在别的文件中。看上去简单的一句话却容易让人犯糊涂首先在使用extern时候要严格对应声明时的格式,在实际编程中,这样的错误屡见不鲜。extern只能修饰全局变量和函数,而且extern只是用来声明变量而非用来定义变量的。函数是默认在前面加个extern的,程序员加与不加都一样的效果。

总结:extern声明的符号说明了三点:

  1. 符号定义在它处
  2. 符号是全局可访问符号
  3. 符号作用域开始 
       有关extern链接的知识点在此文中不提,已经超出C的基础语法之外.

    接下来说说宏函数,讲到宏函数的知识点,一般都有这么一个例子:

    #define max(x,y) (x)> (y)?(x):(y); 宏做的是简单的字符替换,占用的是编译过程的预处理时间,宏的参数
    不占内存时间,宏的参数即没有类型,也不会经过计算得来,没有赋值传参那么一说。

    最后说到数组名和指针,无数的大大告诉我们数组名不是指针,但时仍然有无数人把他们当作一会事,因为在传参时他们
    俩是通用的。那些记着数组名不是指针的菜鸟也仅仅记住了,数组名不能像指针一样被改变值。还有最直观的便是
    sizeof能得出数组占用多少内存而不是指针占用多少内存。数组名作为函数参数时,对其进行sizeof又是指针占
    用内存的大小。其实说白了,这些个乱七八糟的东西只是编译层面的东西,一但编译好了,哪来的数组名,机器码
    层面上只有地址。我抄来一段讲得比较清楚的话:无论数组的类型是什么,数组名都保存着首元素的地址,用数组
    名来引用用元素,编译器能够通过符号表保存着的数组长度信息及类型信息来直接替换成元素的地址,而把数组名
    赋值给指针变量,将会失去数组长度信息,所以必须指定剩下的维数信息。所以我抛开名字定义不讲,数组名更加
    多的是编译层面的语法规则问题,而指针却是实实在在占用了内存。数组名用起来如此像指针只不过正好C语言是
    如此设计的,你的高级语言中右式中写到数组名,编译器在编译时会用地址给替代了而已。


    C语言基础之基础的细节暂时就想到了这么多了。

阅读(1400) | 评论(3) | 转发(0) |
给主人留下些什么吧!~~

陈九CU2013-01-02 21:53:46

pmerofc: #define max(x,y) (x)> (y)?(x):(y);

多个分号.....
you are right。   不小心随手给加上去了,呵呵。。

pmerofc2013-01-02 20:09:40

#define max(x,y) (x)> (y)?(x):(y);

多个分号