嵌入式学习day13

一.预处理命令

分为三种: 1.宏定义         2.文件包含         3.条件编译

代码变成可执行文件:

预处理 ------->  编译 ----------> 链接--------->可执行文件

宏定义

1.不带参数的定义

#define   标识符  内容

#define PI  3.1415              //PI为宏名

int main(void)

{

        printf("%f\n",PI);

        return 0;

}

gcc  -E -Omain.i main.c   

上面指令表示只做预处理,不编译。

计算机会无脑把PI替换成 3.1415。 

宏名所有都需要大写,以和变量区分,且PI不能是左值。

2. 带参数的宏定义

#define  宏名(参数表)  字符串

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

int main(void)

{

        printf("%d\n",ADD(3,4));         //输出为7

        printf("%d\n",ADD(3 > 4,5));   //输出为0, 因为计算机会无脑替换 为  (3 > 4 + 5)                    return 0;                                    //此时输出为假                 

}

因此在宏定义时,应尽量多的带上括号

如在上面的定义中,应尽量写成#define ADD(a,b) ((a) + (b)) 

这样就不容易出现歧义

宏与函数是有区别的,宏是以空间换时间,且代码不具有复用性。

文件包含

#include <math.h>                //可以是相对路径

#include </home/linux/1.txt> //也可以是绝对路径 

当为相对路径时  <    >   会在  /usr/include/    文件夹里面找需要的文件

#include "func.c"  // 会在与当前   main.c 同文件夹  下找该文件

条件编译

#if 0               //相当于把下面的代码注释掉了,非0即为真,也可  #if 1 则会显示下面的代码

int main(void)

{

        return 0;

}

#endif

 

#define  ABC

int main(void)

{

#ifdef   ABC                 //宏定义了ABC则执行下面语句  

        puts("Hello");      //程序段1

#else                            //否则执行下面语句

       puts("World");     // 程序段2 

#endif

}

 一般用于debug

//clock.h文件

struct Clock

{

        int hour;

        int minute;

        int second;

};

//func.c文件

#include "func.h"

void fn(struct Clock c)

{

}

 //func.h文件

#include "clock.h"

extern void fn(struct Clock c);

//main.c文件 

#include "clock.h"         //会无脑拷贝  替换后如下

/*

struct Clock

{

        int hour;

        int minute;

        int second;

}

*/

#include "func.h"            //替换后如下

/*

#include "clock.h"    会再次替换,     替换后与上面出现了同名   struct Clock{ ......}

extern void fn(struct Clock c);

*/

int main()

{

        struct Clock(c);

        fn(c);

        return 0;

}

 会出现编译报错,因为在同一作用域中,不允许出现同名函数。

因此头文件应该改成 

//clock.h文件

#ifndef CLOCK_H      //这样就可以防止同名函数的出现

#define CLOCK_H

struct Clock

{

        int hour;

        int minute;

        int second;

};

#endif

 //func.h文件

#ifndef FUN_H     //如果没有定义FUN_H

#define FUN_H    //则定义FUN_H

#include "clock.h"

extern void fn(struct Clock c);

#endif

二.初识指针

指针是用来装地址的数据类型

定义:

基类型    *指针变量

int main(void)

{

         int i = 10;

         int *p;

         p = &i; 

        *p = 6;                     //这里的  * 是指针运算符,表示指向  p 里面存储的地址  地方的值。                                          // *p与 i 等 效。    属于间接访问  i

         printf("%d\n",i);

         return 0;

}

输出: 6

void fn(int *n)

{

        *n = 100;

int main(void)

{

        int i = 10;

        fn(&i);

        printf("%d\n",i)

        return 0;

}

输出: 100

此时因为传的是  i  的地址  因此 i  的值也会改变,输出为100 

void maxMinOfNumbers(int a,int b,int *max,int *min )

{

      if(a >b)

        {

                *max = a;

                *min = b;

        }  

int main(void)

{

        int a = 10, b = 20;

        int max,min;

        maxMinOfNumbers(a,b,&max,&min);

        printf("%d,%d",max,min);

        return 0;

}

输出: 20,10

 用指针时,就可以实现返回1个以上的结果,而return 一次只能返回一个结果。

int i = 6;

int *p = &i;        //此时 &*p *&p 是等价的,都表示指针p,相当于*与&抵消了

                          //而 *&i 可以,但  &*i  会报错 因为 *  运算符后面必须是地址

 int * t                   

                          // 通常  指针地址是  随机数的,我们把它称为野指针,程序一般会崩溃

指针使用的总结:

1.根据指针变量中的值去内存中定位

2.从定位处开始向后偏移sizeof(基类型)个字节

3.将偏移后的那部分内存空间当作是一个基类型变量来看 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值