C语言预处理、指针

目录

编译过程

(一)预处理

1.宏定义

(1)不带参数的宏定义:

(2)终止宏定义的命令:

(3)带参宏定义:(宏函数)

2.文件包含

<> 和 " " 的区别:

3.条件编译

(二)指针

1.指针的概念

2.定义指针变量

3.指针类型

4.指针变量的引用


编译过程

(1)预处理(预编译)(-E):将代码中相关预处理命令执行,最终产生一个只包含C语言代码的文件。

预处理指令: gcc  -E  file.c  -o  hello.i

(2)编译(.i)(-S):对语法进行检查,将C的源代码生成汇编代码。

编译指令:  gcc  -S  file.c  -o  hello.s

(3)汇编(.s)(-c):表示把汇编源代码最终生成机器代码。

汇编指令:gcc  -c  file.s  -o  hello.o

(4)链接:将使用到的其它代码链接到一起,生成最终可执行文件。(.out)

(一)预处理

1.宏定义
(1)不带参数的宏定义:

#define  宏名   宏值

(#define  标识符  字符串)

注意:

①预处理命令都是以  #  开头的。

②宏名命名规则和之前标识符命名规则一致。(宏名一般都写成大写,以示区分,小写在语法上也是可以的)

③预处理实际上是将宏名宏值(预处理阶段的字符串)原样替换(-----文本替换),但是C语言字符串中出现的“宏名”不会被替换。

④应用:a.提高代码可读性;b.一改全改 ----- 方便代码的修改

eg:#define N 10

含义:表示将来代码中出现的 N 都代表10,则编写代码时可以使用N表示数字10。

(2)终止宏定义的命令:

#undef  宏名   \\表示取消宏名的定义

注意:宏名的作用域只是在预处理阶段发挥作用。

作用范围:# define 命令出现在程序中函数的外面,宏名的有效范围为定义命令之后到本源文件结束;可以用# undef 命令终止宏定义的作用域。

(3)带参宏定义:(宏函数)

#define  宏名(参数)  宏值

eg:#define  ADD(a,b)  a+b

注意:

带参宏 和 函数 有本质的区别:

        a.处理阶段不一样:宏定义----预处理阶段;  函数----编译阶段

        b.使用不一样:宏   ----预处理阶段就结束了,宏的使用本质上是文本的原样替换;

                                函数 ----调用时进行使用,函数的使用本质上是函数代码的调用。

        c.参数:宏的参数只是进行文本替换时用的,不进行语法检查;函数的参数是有类型的,编译阶段是要进行类型检查的。

        d.应用:一般对于一些短小代码(不超过5行的代码),考虑写成带参宏。

        e.宏的副作用:

        处理:把能加括号的都加括号

        f.宏定义必须写在一行

        g.在进行宏定义时,可以引用已定义的宏名,可以层层置换。

2.文件包含

#include  <文件名>

#include  " 文件名"

<> 和 " " 的区别:

查找头文件的方式不一样:

①<>:表示到系统默认的路径寻找对应的头文件。

② " " :表示到当下目录下寻找头文件,如果没有,再到系统默认路径下寻找。

3.条件编译

(1)语法形式1:

#ifdef  标识符

        程序段1

#else 

        程序段2

#endif

①含义:如果定义了标识符,则预处理程序段1(就是将程序段1的代码保留);否则,预处理程序段2。

②用途:a.调试代码;b.设计头文件

(2)语法形式2:

#ifndef  标识符

        程序段1

#else 

        程序段2

#endif

含义:如果没有定义标识符,则预处理程序段1(就是将程序段1的代码保留);否则,预处理程序段2。

(3)语法形式3:

#if  表达式

        程序段1

#else

        程序段2

#endif

含义:表达式为真,处理程序段1;表达式为假,处理程序段2。

(二)指针

1.指针的概念

(1)指针就是地址,地址就是内存单元的编号.

(2)指针也是一种数据类型,这种数据类型是专门处理 地址 这种数据类型。

2.定义指针变量

基类型  *指针变量名

(1)基类型:

①整型、浮点型、字符型、数据类型、结构体类型、函数类型

②作用:表示该指针类型所指向的内存空间存放什么类型的数据。

基类型决定了访问空间的大小

(2) * :定义时,表示此时定义的是一个指针类型的变量。

(3)指针变量名:符合标识符命名规则

注意:在 64 位系统上,指针数据类型通常占用 8 个字节的空间来存储地址。

eg: int  *p; //pointer

int  a = 10; //a所在的空间是用来存放int(整型)类型的数据的

int *p = &a; //p指向了a

&a  //表示获得a所在空间的首地址(取地址先取的是编号小的那部分地址)

3.指针类型

int *  ----这个整体叫指针类型

含义:首先表示是一个指针类型,表示指向 int 型数据的指针类型

4.指针变量的引用

eg:int *p = &a; //p指向了a ---因为p中保存了a的地址

地址 这种数据类型对应 指针类型。

(1)指针运算:

  ----指针运算符,单目运算,运算对象只能是指针(地址)

eg:*p   //表示访问 p 所指向的 基类型 的内存空间 ---间接访问(通过a访问---是直接访问)

访问步骤:①首先拿出p中地址,到内存中定位;

           ②偏移出 sizeof(基类型) 大小的一块空间;

            ③将偏移出的这块空间当作基类型变量来看。

*p 的运算效果相当于就是一个基类型的变量。-----   *p <=> a

  • 8
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值