Day 12 预处理、指针基础

编程流程:编辑--->编译--->运行--->调试

编译的过程

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

(2)编译:对语法进行检查

(3)汇编:将汇编源代码生成机器语言

(4)链接:将使用到的其他代码链接到一起生成可执行文件

预处理命令

        “预处理”,即根据预处理命令对程序作相应的处理(例如,若程序中用#define 命令定义了一个符号常量 A,则在预处理时将程序中所有的 A都 置换为指定的字符串。若程序中用#include 命令包含一个文件"stdio. h", 则在预处理 时将 stdio. h 文件中的实际内容代替该命令)。

C 提供的预处理功能主要有以下 3种: 1. 宏定义 2. 文件包含 3. 条件编译

1、宏定义

不带参数的宏定义

语法:   #define 标识符 字符串

              #define 宏名 宏值

#define N 10

(含义:表示将来代码中出现的N都代表10,编译代码时,可以使用N表示数字10;) 

注意:

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

        ②宏名命名规则和之前标识符命名规则一致(宏名一般都写成大写,以区别普通变量名)

        ③预处理实际上是将宏名用宏值(预处理阶段的字符串)原样替换(文本替换)

        ④应用:a.提高代码可读性

                       b.一改全改,方便代码修改

        ⑤宏的作用域:只是在预处理阶段发挥作用

                    作用范围:从定义处开始到宏名取消

                   #undef 宏名  -----  取消宏名的定义

编辑一个含宏定义的 main.c 文件: 

#include<stdio.h>

#define N 10

int main(void)
{
    int a[N] = {1,2,3,4,5};
 
    int i;
 
    for(i = 0;i < N;++i)
    {
        printf("%d ",a[i]);
    }
    putchar('\n');
 
    return 0;
}

通过使用gcc -E main.c -o main.i预处理命令可在 main.i 查看文本替换:

797 int main(void)
798 {
799  int a[10] = {1,2,3,4,5};
800 
801  int i;
802 
803  for(i = 0;i < 10;++i)
804  {
805   printf("%d ",a[i]);
806  }
807  putchar('\n');
808 
809  return 0;
810 }
带参宏定义

       语法:#define 宏名(参数) 宏值

#define ADD(a,b) a+b

使用示例代码: 

#include<stdio.h>

#define ADD(a,b) a+b

int main(void)
{
    int x = 3;
    int y = 4;

    printf("x+y=%d\n",ADD(x,y)); //预处理中会直接用x,y替换带参宏定义中的a,b 

    return 0;
}

注意:

①带参宏和函数的本质区别

   a.处理阶段不一样

             宏定义 ------ 预处理阶段

             函数 ----- 编译阶段

   b.使用不一样

             宏 ----- 预处理阶段就使用结束了,宏的使用本质上是文本替换,不进行语法检查

            函数 ----- 调用时,进行使用;函数使用本质上是函数代码的调用,函数的参数是有类型                  的,编译阶段是要进行类型检查。

  c.应用

            一般对于一些短小代码(不超过5行代码),考虑写成带参宏

  d. 宏的副作用

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

例如:

#define MUL(a,b) a*b

printf("a * b = %d\n",MUL(1+2,3+4));//文本替换后为1+2*3+4

结果为:a * b = 11 

( 为考虑运算优先级的结合性在宏定义中加上括号 ((a)*(b)) ,加括号后运行结果为 21)

  e. 宏定义必须在一行

2、头文件

#include<文件名>

#include"文件名

<>与" " 区别

①查找的路径不同

           <> 到系统默认的路径寻找对应头文件;" " 表示先到当下目录下寻找头文件,如果没有,再到系统默认路径下寻找。

3、条件编译

如果标识符被定义了,则预处理(保留)程序段 1,否则保留程序段 2 

#ifdef 标识符

    程序段 1

#else

    程序段 2

#endif

如果没有定义标识符,则预处理程序段 1,否则预处理程序段 2

#ifndef 标识符

    程序段 1

#else

    程序段 2

#endif

表示式为真处理程序段 1,表达式为假处理程序段 2

#if 表达式

    程序段 1

#else

    程序段 2

#endif

#ifndef _ADD_H

#define _ADD_H

指针基础

1、指针概念

        地址——内存单元的编号

        指针就是地址,指针类型 —— 处理指针(地址)数据

        指针也是一种数据类型,专门用来处理地址这种数据

2、指针变量定义及引用

指针变量定义

                             基类型 *指针变量名

    (1)基类型:整型、浮点型、字符型、数据类型、指针类型(数据类型、结构体类型)

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

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

      指针类型 int *p  //int整体叫指针类型

 指针变量的引用

         int a = 10;

         int *p = &a;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值