C扩展知识

大一学习C时的学习笔记,放出来共享下,嘻嘻。不过当时使用的编译器是TC或者VC6.0,即使用的C标准是C90而非最新的C99标准,故和现在的编译结果有些许出入。当然学习以动手为主,照搬书上的知识是学不到任何东东的。本文仅供拓展自我使用。

 

C扩充知识 (2008年2月13日整理)

1.变量的声明和定义:
#1.带有初始化的语句是定义。如:int a = 1; /* 定义 */
#2.带有 extern 的语句是声明(除非对变量进行重新初始化)[尽量不要,会产生二义性,但系统会当成定义同时警告]
如:extern int a; /* 声明 */
extern int b = 2; /* 定义,但系统会警告,尽量不用 */
#3.既没有初始化又没有 extern 的语句是“暂时定义(tentative definition)”
如:int a; /* 暂时定义 */
[注:暂时定义是C语言特有的,C++没有这个概念,相反,C++推行“只定义一次”原则(one definition rule),这导致在C里面是

暂时定义的语句在C++里都是C正式的定义。为防止之间迁移带来的问题,最好要么声明,要么定义,并且只能定义一次。

2.编译和链接:
分为四个阶段,分别由不同的程序完成:
第一阶段:由预处理程序执行C源文件中的预处理指令;
第二阶段:C编译器把经过预处理的C代码文件编译成汇编代码文件;
第三阶段:汇编编译器把汇编代码文件编译成目标代码文件;
第四阶段:链接程序把所有目标代码链接起来产生可执行文件。

3.对齐(alignment)(TC中未发现使用):
为了提高效率,编译器一般都会把数据安放到适合它们的地址。譬如int占4个字节,则凡是int变量的地址都是4的倍数,称为“4字

节对齐”。此时其他数据也会依照该规则分配空间。

struct s
{ char a;
int b;
}
此时该结构体内存分配为
       ┌───────┐┐
       │  char │┆
       ├───────┤4字节
       │   空  │┆
       ├───────┤┤
       │   int   │4字节
       └───────┘┘
       
因此此结构占用8字节内存空间,而非5字节。

4.词法分析:
“最大匹配“原则”:编译器(包括预处理程序和编译程序)在遇到“空白”(如空格、回车、制表符等)之前,以能够取得的、

有意义的、最长的字符作为记号。

5.注释注意与原则:
C90标准中只有一种注释风格,就是使用“/*”和“*/”。
注意该风格不支持嵌套使用,
即/* something /* something else */ */
编译时第一个“/*”和第一个“*/”的内容全部被屏蔽,而留下最后一个“*/”,这样便导致了编译错误。
目前大部分编译器都“暗中”支持“//”的使用
原则:
#1. 字符串里面的注释等不起注释作用;
#2. 注释符里的双引号不起标识字符串的作用;
#3. 如果情况混乱则从头找起。

6.typedef注意:
#1. typedef 跟变量一样有可视范围,并且内层的可以覆盖外层的。
#2. (在同一作用范围内)不能用相同的名字定义不同的数据类型。
如:

typedef int INT32;
typedef long INT32; /*ERROR*/

 

C语言中一模一样的typedef不能重复出现

typedef int INT32;
typedef int INT32; /*ERROR*/

 

但C++中正确。

#3.用typedef定义的类型不能“组合使用”

typedef int INT32;
unsigned INT32 a; /*ERROR 此时用#define解决*/

 

#4. typedef char * String;
const String s;
等价于 char* const s; 而非 const char * s;

因为当用 typedef 定义了一种新的类型 String 之后,const 修饰的对象就是 String,而 String本身是指针,于是 const

String 的意思就是 String (某种指针)的值是常量,所以最后 s 就被理解为指向 char 的 const 指针。

7.源代码行可以在下一行继续,只要在第一行末尾加上反斜杠(“\”)。或标准C语言三字符组 ??/
例:

if (a == b) x = 1; el\
se x = 2;
// 等价于:
if (a == b) x = 1; else x = 2;

 

8.宏定义中:
#把宏参数变为字符串 #define s #abc 展开为“abc”
##把两个参数贴合在一起 #define A a##b 展开为“ab”

9. 定义了数组后,数组名不完全等同于指针。因此,可用sizeof(a)/sizeof(a[0])求数组长度。
如:

int a[10], * p;
p = a;
// sizeof(a)为40;
// sizeof(p)为2;

 

10.const区别注意:
1. const int a;
2. int const a;
3. const int * a;
4. int * const a;
5. int const * a const;

1、2作用一样:a是一个常整型数。3中a是指向一个常整型数的指针(整型数不可变,指针指向可变)
4中a是指向整型数的常指针(指向的数可变,指针指向不可变)。
5中a是指向常指针(都不可变)

11.#、##补充:
宏扩展期间,#和正式参数名换成相应的包含在字符串引号当中的实际参数。生成字符串时,记号参数表中的每个空白序列换成一个

空格符,任何嵌入引号和反斜杠前加上一个反斜杠以保留其在字符串中的含义。参数开头和末尾的空白符忽略。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值