预处理:
编程流程
1.编辑
2.编译
3.运行
4.调试
编译过程:
1.预处理 //预编译----将代码中相关 预处理命令执行 最终生产一个 只包含C语言的代码文件
// gcc main.c -E -o main.i
2.编译
// 编译----对语法进行检查,将这个c的代码
3.汇编
// 表示将 汇编源代码 最终生成 机械代码 // gcc -c main.s -o main.o
4.链接
将使用到的其他代码连接到一起 最终生成可执行文件 //gcc main.o -o main
预处理:// 作 文本的替换
宏定义
语法:
#define 标识符 字符串
#define 宏名 宏值
注意:
1预处理命令 都是以 # 开头的
2.宏名 命名规则
宏名 一般都大写 以区分与普通变量名
#define n 10
含义:
表示将来代码中出现的 N 都表示10
例:
#include<stdio.h>
#define PI 3.14
int main()
{
int r;
scanf("%d",&r);
printf("L = %lf\n",2*r*PI);
printf("S = %lf\n",r*r*PI);
return 0;
}
代码中出现的PI 都为 3.14
2.文件包含
3条件编译
# undef N 取消宏名的定义
注意;
只是在预处理阶段发挥作用
作用的范围 :
从定义处开始 ,到 #undef 结束
带参宏定义:
语法:
#define 宏名(参数)
注意:
1.带参宏 和函数有本质区别
.处理阶段不一样
宏定义----预处理阶段
函数-----编译阶段
使用不一样
宏 ----- 预处理阶段 就是用结束了
宏的使用,本质上,是文本的原样替换
宏的参数,只进行 文本替换 用 ,不进行语法检查
函数 ----- 调用时进行
函数的使用,本质上时函数代码的调用
函数的参数,是由类型的,编译阶段是要进行类型检查的
应用
对于一些短小的代码,考虑携程带参宏
宏的副作用
处理:
能加括号的加括号
宏定义 一定要写在同一行
写在多行 要用 \ 续航符 但是后面不能加空格
文件包含
#include <文件名>
#include ”文件名“
区别:
<> // 到系统默认的路径寻找对应的头文件
“ ”// 表示先到当下目录下寻找头文件,如没有,再到系统默认路径下寻找
条件编译
(1)
#ifdef 标识符
程序段1
#else
程序段2
#endif
含义:如果定义了标识符则预处理程序段1
否则处理程序段2
(2)
#ifndef 标识符
程序段1
#else
程序段2
#endif
含义:如果没有定义标识符则预处理程序段1
否则处理程序段2
(3)
#if 表达式
程序段1
#else
程序段2
#endif
含义:表达式为真,处理程序段1;表达式为假,处理程序段2
指针
指针基础
指针概念
指针变量定义及引用
指针传参
指针进阶
指针+一维整型数组
指针+一维字符型数组
指针高级
指针+二维整型数组
指针+二维字符数组
指针的数组
指针+函数
指针+指针
指针概念:
地址 内存单元的编号
指针 就是 地址
指针 也是一种数据类型
指针类型
是专门用来处理 地址 这种数据
1.基类型
作用:表示该指针类型
语法:
基类型*指针变量名
&a 取地址 获得a所在空间的首地址
表示 获得了一块 可以存放
int * 首先表示一个 指针类型
表示指向int型 的指针类型
* // 指针运算符
// 单目运算
// 运算对象-----只能指针(地址)
*p // 表示访问 p所指向的 基类型的 内存空间
*p // 间接访问
// 通过a访问的 ---- 直接访问
step1:首先拿出p中地址,到内存中定位
step2:偏移出sizeof(基类型)大小的一块空间
step3:将偏移出的这块空间,当做一个基类型来看
*p // 相当于就是一个基类型的变量
#include<stdio.h>
int main()
{
int a = 0X12345678;
int *p = &a;
printf("%#x\n",a);//1
printf("%#x\n",*p);//2
printf("%p\n",p);//3
printf("%p\n",&a);//4
return 0;
}
1 2输出为0X12345678
3 4 则输出a的地址