脚本宝典收集整理的这篇文章主要介绍了当你敲完Hello World后的第一步——C,脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
“江山如画,一时多少豪杰——时二二年五月六日”
了解敲完hello world后,编译器是怎么处理代码的第一步的呢,这是学习C和C++的基础。 Hello World代码如下。放错了,重来。
代码如下 当你敲完Hello World这串代码时。编译器会对这些代码进行编译 和 链接的操作。而 编译: 又分为 预处理、编译、汇编。 所以说 当你敲完C代码后的第一步,编译器会对C代码进行预处理.
那么预处理主要做了那些事情呢F1f;
预处理大致做了以下事情: 1.定义和替换由 #define指令定义的符号 2.删除注释 3.确定代码部分内容是否应该根据一些 条件编译指令 进行编译 4.插入被 #include指令包含的内容
所以本章详解预处理指令 #define、#include、条件编译指令。
什么是宏? 宏的定义:#define 允许把参数替换到文本中,这种实现通常称为宏或定义宏
宏的声明格式:
#define NamE stuff
解释:没当有符号name出现在#define NAME stuff这条语句后面时,预处理器就会把它替换为 stuff。 NAME: 1.NAME是宏的名字。在这里 name 相当于变量,或者也可以相当于函数。但不等于函数! 2.一般NAME都是大写,因为宏和函数语法很相似,语言本身我们无法区分,所以宏名要全部大写 stuff:可以是常量。可以是表达式。也可以是一段程序。
例如: 以下代码在预处理后是什么样子呢?
//定义声明宏
//定义中我们使用了括号,这是一个好习惯,避免优先级的错误
#define SQUARE(x) (x)*(x)
int main()
{
PRintf("%d ", SQUARE(5));
return 0;
}
预处理后的代码,以下你看到的代码是编译器实实在在的处后的代码。
#define SQUARE(x) (x)*(x)
int main()
{
//将SQUARE(5)替换为(5)*(5)
printf("%d ", (5)*(5));
return 0;
}
你是否还对#define 替换迷惑?请继续往下看
到底上面的代码是怎么替换的 宏? 1.再调用宏时,首先对参数检查,看是否包含了#define定义的符号,比如SQUARE(5),然后将它的x * x替换为5 * 5. 2.对于宏,参数名被他们的值所替代。 3.最后,再次对文本扫描,看是否包含了热任何由#define定义的符号。如果是,就重复上述处理过程。
为什么会有第3步的重复呢? 因为有时候#define定义可以包含其他#define定义的符号。但是宏不可以递归!
什么是带副作用的宏参数? 副作用:就是表达式求值的时候出现的永久性效果。
例如:
x+1;//不带副作用
x++;//带有副作用
下面代码输出结果是什么?
#include <stdio.h>
#define ADD(a, b) (a)+(b)
int main()
{
int x = 2;
int y = 3;
int z = ADD(x++, y++);
//输出的结果是什么?
//x=3 y=4 z=5
printf("x=%d y=%d z=%dn", x, y, z);
return 0;
}
因为被替换的代码是int z = ADD(x++, y++); 替换后为:int z = (x++)+(y++);
这样结果就一目了然。
#undef:这条指令用于移除一个宏定义 例如:移除MAX这个宏。
什么是条件编译? 意思就是我们可以选择性的编译。 条件编译:你可以选择代码的一部分是被正常编译还是完全忽略。用于支持条件编译的基本结构是#if指令和与其匹配的#endif指令。
常量表达式exPression,由预处理器求值。 如果expression为真,那么statements将被执行,否则预处理器就安静的删除它们。
#if expression
statements;
#endif
//常量表达式expression,由预处理器求值。
同if else语句,为真则执行。
#if expression
//...
#elif expression
//...
#else
//...
#endif
为了测试一个符号是否已经被定义。在条件编译中完成这个任务更方便。
以下两条语句功能想通过。
1.#if defined(symbol)
2.#ifdef symbol
某个程序既要在windows系统下能够运行,也需要在linux系统下运行,这就要条件编译来解决跨平台问题。这时候嵌套指令很容易解决。
#if defined(OS_UNIX)
#ifdef OPTIOn1
unix_version_option1();
#endif
#ifdef OPTION2
unix_version_option2();
#endif
#elif defined(OS_MSDOS)
#ifdef OPTION2
msdos_version_option2();
#endif
#endif
#include在预处理时会被展开。 这种展开的方式很简单: 1.预处理器先删除这条指令,并用**#include**所包含文件的内容替换。 2.这样一个源文件被包含10次,那就实际被编译10次。
#include "Add.h"
查找方法: 1.先在源文件所在目录下查找 2.如果该头文件未找到,编译器就像查找库函数头文件一样在标准位置查找头文件。
#include <stdio.h>
查找方法:查找头文件直接去标准路径下去查找,如果找不到就提示编译错误。
这样是不是可以说,对于库文件也可以使用 “” 的形式包含? 答案是肯定的,可以。 但是这样做查找的效率就低些,当然这样也不容易区分是库文件还是本地文件了。
有时候会重复包含头文件,以前为了解决这个方法,人们用了条件编译。代码如下 每个头文件的开头写:
例如有个test.h的头文件。用下划线分开头文件。全大写。
#ifndef __TEST_H__
#define __TEST_H__
//这里面写头文件的内容
#endif
上面这种写法比较古老。 现在一般用这个写法
#pragma once
#pragma once也是是用来防止头文件被包含的。
以上是脚本宝典为你收集整理的当你敲完Hello World后的第一步——C全部内容,希望文章能够帮你解决当你敲完Hello World后的第一步——C所遇到的问题。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。