C语言基础:预处理命令 指针
2026/8/5 9:35:55 网站建设 项目流程

预处理命令

1.gcc编译的4个步骤

gcc main.c------>a.out

预处理:展开和#相关的代码:展开头文件、展开宏、处理预处理命令(条件编译)

#include<stdio.h>

#define PI 3.14

#if 0

#endif

gcc -E(生成预处理阶段的代码) main.c -o(重命名) main.i

编译:将c语言程序转换为汇编指令

gcc -S main.i -o main.s

汇编:将汇编指令转换成二进制可执行程序

gcc -c main.s -o main.o

链接:将库函数链接起来(库函数的实现

gcc main.o -o main

2.预处理命令

(1)宏定义

不带参宏:符号常量

#define 符号常量 值

#define PI 3.1415

带参宏:宏函数

#define 符号常量(参数1,参数2,...) 宏的实现

#define ADD(a,b) ((a)+(b)) //求和

#define MAX(a,b) ((a)>(b)?(a):(b)) //比大小

注意:

1.宏作为预处理命令,负责在预处理阶段展开,不做运算,只是代码的替换

2.宏名要大写,宏后不能加分号

3.宏值只是代码的替换,能加括号就加括号

4.宏和函数的区别:

宏是预处理阶段代码替换,会使代码体积增大;

函数时运行时的调用,需要保护现场和恢复现场

(2)头文件

头文件存放:

1.其他头文件

2.声明的数据类型

3.宏定义

4.函数和全局变量的声明

源文件只存放头文件#include "头文件.h"

注意:

1.<>表示包含的是系统头文件,让编译器从系统路径下找:/usr/include

2." "表示包含的头文件是用户自定义,让编译器从当前路径下找

(3)条件编译

1.防止头文件重复包含

#ifndef __大写文件名_H__

#define __ 大写文件名_H__

//头文件内容

#endif

根据宏有没有被定义过,决定头文件中的内容要不要加入编译中

2.条件编译

#if 0 //不编译

#endif

#if 1 //编译

#endif

根据逻辑表达式的结果,为真则编译,为假不编译

#ifdef 宏名 //若该宏有被定义,则编译;若没有,则执行else

#else

#endif

:vsp 文件名.c----》打开双屏

:sp 文件名.c-----》横向打开双屏

:set mouse=a-----》光标转换

:wqa------》全部退出并保存

ctrl+ww

指针

内存:程序运行过程中,可以访问到的内存存储空间;计算机为了方便对内存的管理,以字节为单位,对内存进行了编号

地址(指针):内存的编号,指针指向了一个具体的空间

指针变量:保存地址的一个变量,需要占用8字节内存空间

1.指针基础

(1)定义指针变量

基类型 *变量名

基类型:指针所指向的空间内,存储的数据类型(int、char、float、void、构造数据类型...)

*:类型说明符,说明后面的变量是一个指针

变量名:遵循标识符命名规则(p开头)

pmax、ptmp...

int *pi,*pj;

char *pch;

指针变量中保存的地址,是该数据的首地址

sizeof(指针);在64位计算机系统下,内存中占用8字节;在32位计算机系统,占4字节

(2)指针变量的初始化和赋值

int *p=NULL;

野指针:未初始化或未赋值,或指向一个已释放内存空间的指针。

操作有风险,可能导致程序崩溃;因此避免野指针:

1.给指针初变量始化成空指针NULL(本质是(void*)0)

2.给指针变量初始化成已有变量的地址

(3)指针的运算符

* 指针运算符

用于访问数据

*指针变量;------》指针降级为变量类型-----》基类型

int *p;

p------》int*

*p-----》int

注意:

1. * 只能放在指针变量前面

2. *p,访问指针变量的数据------》指针降级为变量类型-----》基类型

3. *p,访问的字节数取决于该指针的基类型

char *p; *p---->char,访问1字节

int *p; *p---->int,访问4字节

double *p; *p---->double,访问8字节

& 取地址运算符

&num;

取某变量的空间首地址

注意:

1.&只能给变量取地址,常量和表达式不行

2.&获取的是这个变量的首地址

(4)指针的算术运算

+ * / % 对指针运算没有意义

- 指针1-指针2; 两个指针之间相隔的元素个数=(地址之间的字节差/sizeof(基类型))

++ 指针+1:表示从当前地址向后偏移sizeof(基类型)个字节

-- 指针-1:表示从当前地址向前偏移sizeof(基类型)个字节

char *p; p+1;---->向后偏移1字节

%p打印地址

2.指针作为函数参数

1.被调函数中,想要修改主调函数中定义的变量,必须地址传递

2.被调函数中,想要仅使用主调函数中定义的变量,既可以值传递也可以地址传递

3.被调函数需要返回多个结果时,可以传递主调函数多个变量的地址,地址指向的空间可以保存被调函数得到的结果

3.指针和一维整型数组

数组的数组名就是数组首元素地址

int a[5]={0}; printf("a=%p\n",a); printf("a[0]=%p\n",&a[0]);

注意:

1.数组名为一个地址常量(右值),不能为其赋值 a=&num;×

一维整型数组作为函数参数传递

两种写法 void printf(int a[ ],int len) void printf(int *pa,int len)

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询