翁恺 程序设计进阶C语言笔记-宏与大文件结构

编译预处理与宏
  • #开头的是编译预处理指令,他会在正式编译以前,将所有定义的预处理的名称换成值,名称只能是单词,值可以是各种东西
  • 本质上就是替换,就是给一个常量,语句取个名字,编译器就会把有这个名字的地方原封不动的替换为宏的值
  • 它们不是C语言的成分,所以不加分号
  • #define来定义一个宏
//用宏定义一个常量
#difine PI 3.1415926    
//等效于
const double PI = 3.1415926;

//定义一个语句  注释
#define PI2 2*PI     //注释

//反斜杠表示与下一行接起来
#define RPT printf("%f ",PI);  \
                     printf("%f ",PI2) 
int mian(void )
{
    PRT;   //因为这里有了个分号,上面就不需要带分号了
}

//没有值的宏,在语法上也是允许的
#ifndef _NODE_H_
#define _NODE_H_

//预定义的宏,编译器自带的
__LINE__      //当前行号,整数
__FILE__      //当前文件名,字符串,下同
__DATE__
__TIME__
__STDC__      //当要求程序严格遵循ANSIC标准时该标识符被赋值为1,主要是判断我们的程序文件是不是标准C程序。

#define PRT printf("%s",__DATE__);

int main(void)
{
    PRT
}

//带参数的宏
//为了避免因为运算优先级带来的问题
//整个宏的值要有括号,任何参数出现的地方要有括号

#difine cube(x) ((x)*(x)*(x))

int i = 1;
cube(i+2);            //这里如果x不带括号,就会出问题

//多个参数的宏
#define MIN(a,b) ((a)>(b)?(b):(a))

在gcc中有办法可以看到编译过程的文件

$gcc test.c --save-temps 
$ls -l

系统 .c -> .i -> .s ->.o -> .out

.i就是中间文件,此时预处理名称全部被替换成值了

部分宏可以被inline函数替代

大程序结构

#include xx.h

  • include “” 现在.c目录所在的文件夹中去找,然后再去编译器指定的目录去找,自己定义的.h文件就用""
  • included <> 只会在编译器指定的目录底下去找,适用于包含标准库的头文件。
  • indlude不是用来应用库的,它是**做函数声明的,确保你在调用函数时给出的参数是正确的类型。**在xx.h中将要用到的函数的原型声明放进去,include的作用就是把文件里的所有内容原封不动的插入到他所在的那一行。stdio.h中只有printf的声明,printf的源代码在.lib文件夹中
  • 将所有公开的函数原型和全局变量放在.h文件中,使得他可以在多个.c文件中共享。
  • 定义和声明,定义产生代码,声明不产生代码,全局变量的声明不产生代码
//在test.h中
int max(int a,int b);      //函数的声明
extern int a;   //变量的声明,告诉编译器,这个变量是个int类型,可以被其他文件调用
  • 在全局变量中加上static就使得他成为只能在所在的编译单元中被使用的全局变量。

  • 重复声明和头文件结构

truct point{
    int x;
    int y;
}j;   

truct point{
    int x;
    int y;
}j;   

//如果像这样重复引用,当然是错的,两个重名的结构体了
//如果这个定义定义在a.h中
//再定义一个b.h,b.h中include了a.h
//那么我们include a.h,再Include b.h时就会出现像刚刚一样的重复引用
//所以加入保护,让头文件只被调用一次

#ifndef  __A_H__
#define __A_H__

#endif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值