目录
4.宏名的作用域:从定义那行到代码下面全部(宏和宏之间可以嵌套使用,不分定义的前后位置)。即使放在{}里面作用域与一样。
指针概念:指针就是地址,内存单元(一个字节即为一个内存单元)的编号
预处理过程:
预处理流程:
1 .编辑 2.编译 3.运行 4.调试
编译过程:
1.预处理
//将代码中相关预处理命令执行,最终生成一个只包含C语言代码的文件
2.编译
//对语法进行检查,将这个c的源代码生成汇编代码
3.汇编:
//表示将汇编源代码最终生成机器代码
4.链接:
//将使用到的其他代码链接到一起,生成可执行文件(修改权限命令 chomd +x main.o)
宏定义:
语法:#define 标识符 字符串(#define 宏名 宏值)
eg:define N 10
含义:表示将来代码中出现的N都代表10
预处理命令将宏值进行文本替换
假设 #define N 10;(加了分号)
预处理命令替换文本为原样替换(printf("%d",N)原样替换为printf("%d",10;))分号也直接替换过来
1 #include <stdio.h>
2 #define N 10;
3
4 int main()
5 {
6 printf("%d",N);
7
8 return 0;
9 }
预处理直接原样替换(10;)到N;
int main()
{
printf("%d",10;);
return 0;
}
1.预处理命令一般用#开头
2.宏名命名规则与标识符相同
3.应用:①提高代码可读性②一改全改,方便代码修改
4.宏名的作用域:从定义那行到代码下面全部(宏和宏之间可以嵌套使用,不分定义的前后位置)。即使放在{}里面作用域与一样。
除非定义#undef取消宏名的定义时作用域就在#define到#undef之间。
带参宏定义:宏函数
语法:#define ADD(a,b) a*b
#include <stdio.h>
#define ADD(a,b) a+b
#define SUB(a,b) a-b
#define MUL(a,b) a*b
#define DIV(a,b) a/b
int main()
{
int a,b;
scanf("%d %d",&a,&b);
printf("a + b = %d\n",ADD(a,b));
printf("a - b = %d\n",SUB(a,b));
printf("a * b = %d\n",MUL(1+2,3+4));
printf("a / b = %d\n",DIV(a,b));
return 0;
}
文本直接替换(1+2*3+4),与我们想要的结果不同,所以避免出现这种情况应该在宏定义时加括号,防止优先级破坏你想要的效果。
int main()
{
int a,b;
scanf("%d %d",&a,&b);
printf("a + b = %d\n",a+b);
printf("a - b = %d\n",a-b);
printf("a * b = %d\n",1+2*3+4);
printf("a / b = %d\n",a/b);
return 0;
}
注意:带宏参数和函数有本质区别:
①处理的阶段不一样:宏定义在预处理阶段;而函数在编译阶段。
②使用不一样:
宏:
1.预处理阶段就使用结束了,宏的使用;本质上时文本的原样替换。
宏参数:
2.宏的参数:只是文本的替换,不进行语法检查。
函数:
1.在调用时使用(即函数的使用,本质上是函数代码的调用)
2.函数参数:函数的参数是有类型的,编译阶段要进行类型检查
带参宏的应用:一般对于短小的代码,考虑写成带参宏
(可以减少函数的调用,减少函数压栈的步骤,提高效率)
文件包含:
①#include <文件名>②#include "文件名"
<>与""的区别:
<>:到系统默认的路径下寻找对应的头文件
“”:表示先到当下目录下找到头文件,如果没有,再到系统默认路径下寻找
3.条件编译:
①:#ifdef 标识符
程序段1:
#else
程序段2:
哪个条件符合,在预处理就处理哪个代码段,不成立那个不出现在预处理中
用途:①调试代码②设计头文件
②:#if 表达式
程序段1;
#else
程序段2;
表达式为真则执行代码程序段1,假则执行表达式2;
指针
指针概念:指针就是地址,内存单元(一个字节即为一个内存单元)的编号
指针数据类型:处理指针(地址)数据
指针也是一种数据类型;这种数据类型专门用来处理地址这种数据。
指针变量的命名:
数据类型 + 变量名
语法:基类型* 指针变量名
基类型(即数据类型:整型、浮点型、字符型、数组型、结构体类型等)
eg:
int* p;p即为指针变量
int a;//a所在的内存空间是用来存放int的数据类型的
float b = 10;
int *p =&a;(✔) a的数据类型为int型,&a的数据类型为int*类型
&a含义:①表示获得a所在空间的首地址;②表示获得了一块可以存放int型数据的内存空间的地址
int* p;int*含义:① 表示这是一个指针类型 ②表示指向int型数据的指针类型
2.指针类型:int*整体类型叫指针类型
3.指针变量的引用:
int a = 10;
int *p = &a;//p指向了a(因为p中保存了a中的地址)
指针运算符:*为单目运算,运算对象只能是指针(即地址)
*p表示访问p所指向的基类型的内存空间。
通过*p访问为间接访问,通过a的访问为直接访问
int *p = &a;
解析:
step1:首先拿出p中的地址,到内存中定位
step2:看p的类型,偏移出sizeof(基类型)大小的一块空间
step3:将偏移出的这块空间,当作一个基类型变量来看。