C语言源文件要经过编译、链接才能生成可执行程序:

  1. 编译(Compile)会将源文件(.c文件)转换为目标文件。对于 VC/VS,目标文件后缀为.obj;对于GCC,目标文件后缀为.o。
  2. 链接(Link)是针对多个文件的,它会将编译生成的多个目标文件以及系统中的库、组件等合并成一个可执行程序。

预处理主要是处理以#开头的命令

#include <stdio.h>

//不同的平台下引入不同的头文件
#if _WIN32 //Widows平台
#include <windows.h>
#elif __linux__  //识别linux平台
#include <unistd.h>
#endif

int main(int argc, const char * argv[]) {
    //不同的平台下调用不同的函数
    #if _WIN32 //widows
    Sleep(5000); //Windows 平台下的暂停函数的原型是void Sleep(DWORD dwMilliseconds)(注意 S 是大写的),参数的单位是“毫秒”
    #elif __linux__ //linux
    sleep(5); //Linux 平台下暂停函数的原型是unsigned int sleep (unsigned int seconds),参数的单位是“秒”,
    #endif
    return 0;
}

include用法

#include 叫做文件包含命令,用来引入对应的头文件(.h文件)。用法有两种:
1.#include <stdHeader.h>
2.#include "myHeader.h"

使用尖括号< >和双引号" "的区别在于头文件的搜索路径不同:

  • 使用尖括号< >,编译器会到系统路径下查找头文件;
  • 而使用双引号" ",编译器首先在当前目录下查找头文件,如果没有找到,再到系统路径下查找。
  • 一般习惯是使用尖括号来引入标准头文件,使用双引号来引入自定义头文件(自己编写的头文件),这样一眼就能看出头文件的区别。

define

宏定义命令,就是用一个标识符来表示一个字符串,如果在后面的代码中出现了该标识符,那么就全部替换成指定的字符串。

#define  宏名  字符串
  • 宏定义是用宏名来表示一个字符串,在宏展开时又以该字符串取代宏名,这只是一种简单粗暴的替换。字符串中可以含任何字符,它可以是常数、表达式、if 语句、函数等,预处理程序对它不作任何检查,如有错误,只能在编译已被宏展开后的源程序时发现。
  • 宏定义不是说明或语句,在行末不必加分号,如加上分号则连分号也一起替换。
  • 宏定义必须写在函数之外,其作用域为宏定义命令起到源程序结束。如要终止其作用域可使用#undef命令。
  • 代码中的宏名如果被引号包围,那么预处理程序不对其作宏代替
  • 宏定义允许嵌套,在宏定义的字符串中可以使用已经定义的宏名,在宏展开时由预处理程序层层代换。
  • 习惯上宏名用大写字母表示,以便于与变量区别。但也允许用小写字母。
  • 可用宏定义表示数据类型,使书写方便

带参数的宏

#define 宏名(形参列表) 字符串
例:
#define M(y) y*y+3*y  //宏定义
k=M(5);  //宏调用
//在宏展开时,用实参 5 去代替形参 y,经预处理程序展开后的语句为k=5*5+3*5。
  • 带参宏定义中,形参之间可以出现空格,但是宏名和形参列表之间不能有空格出现。
  • 在带参宏定义中,不会为形式参数分配内存,因此不必指明数据类型。而在宏调用中,实参包含了具体的数据,要用它们去替换形参,因此实参必须要指明数据类型。这一点和函数是不同的:在函数中,形参和实参是两个不同的变量,都有自己的作用域,调用时要把实参的值传递给形参;而在带参数的宏中,只是符号的替换,不存在值传递的问题。
  • 在宏定义中,字符串内的形参通常要用括号括起来以避免出错。
    注:带参数的宏和函数很相似,但有本质上的区别:宏展开仅仅是字符串的替换,不会对表达式进行计算;宏在编译之前就被处理掉了,它没有机会参与编译,也不会占用内存。而函数是一段可以重复使用的代码,会被编译,会给它分配内存,每次调用函数,就是执行这块内存中的代码。

##的用法

##称为连接符,用来将宏参数或其他的串连接起来。

#define CON1(a, b) a##e##b
#define CON2(a, b) a##b##00
printf("%f\n", CON1(8.5, 2));
printf("%d\n", CON2(12, 34));
//展开为
printf("%f\n", 8.5e2);
printf("%d\n", 123400);

常用宏

ANSI C 规定了以下几个预定义宏,它们在各个编译器下都可以使用:

  • __LINE__:表示当前源代码的行号;
  • __FILE__:表示当前源文件的名称;
  • __DATE__:表示当前的编译日期;
  • __TIME__:表示当前的编译时间;
  • __STDC__:当要求程序严格遵循ANSI C标准时该标识被赋值为1;
  • __cplusplus:当编写C++程序时该标识符被定义。

标签: none

添加新评论