嵌入式c语言——学习笔记

嵌入式c语言——学习笔记2

一、Typedef

typedef 在代码中用得最多的就是定义结构体的类型别名和枚举类型


struct _GPIO
{
__IO uint32_t CRL;
__IO uint32_t CRH;
…
};

定义了一个结构体 GPIO,这样我们定义变量的方式为:

struct _GPIO GPIOA;//定义结构体变量 GPIOA

但是这样很繁琐, MDK 中有很多这样的结构体变量需要定义。这里我们可以为结体定义一个别名 GPIO_TypeDef,这样我们就可以在其他地方通过别名 GPIO_TypeDef 来定义结构体变量了。方法如下:

typedef struct
{
__IO uint32_t CRL;
__IO uint32_t CRH;
…
} GPIO_TypeDef;

Typedef 为结构体定义一个别名 GPIO_TypeDef,这样我们可以通过 GPIO_TypeDef 来定义结构体变量:

GPIO_TypeDef GPIOA,GPIOB;

这里的 GPIO_TypeDef 就跟 struct _GPIO 是等同的作用了。除了用在结构体上,typedef类型别名也大量用在int、short等这种变量上。

二、结构体

声明结构体类型:

            Struct 结构体名{
             成员列表;
            }变量名列表;

例如:

Struct U_TYPE {
Int BaudRate
Int WordLength;
}usart1,usart2;

在结构体申明的时候可以定义变量,也可以申明之后定义,方法有:Struct 结构体名字 结构体变量列表 ;

例如:

struct U_TYPE usart1,usart2;

结构体成员变量的引用方法是:结构体变量名字.成员名

比如要引用 usart1 的成员 BaudRate,方法有:

usart1.BaudRate;

结构体指针变量定义也是一样的,跟其他变量没有啥区别。

例如:

struct U_TYPE *usart3;//定义结构体指针变量 usart1;

结构体指针成员变量引用方法是通过“->”符号实现,比如要访问 usart3 结构体指针指向的结构体的成员变量 BaudRate,方法有:

Usart3->BaudRate;

使用结构体的好处是防止函数的入口参数过多,当然也利于增加变量时不用修改函数定义,对于一组描述同一对象的参数,用结构体使他们形成一个整体,也有利于代码的可读性,不会使变量定义显得混乱。

三、宏定义

宏定义用法:

1、宏常量:我们最常使用到的#define的用法就是用#define来定义一个符号常量,而要修改时,只需修改#define这条语句就行了,不必每处代码都修改

例如:

#include"stdio.h"
#define PI 3.14
#define STR "圆周率约等于"
int main()
{
	printf("%s %f",STR,PI); //预处理时会被替换为 printf("%s %f","圆周率约等于",3.14);
	return 0;
}

2、宏语句:我们还可以用宏定义一条或多条语句

例如:

#include"stdio.h"
#define Print printf("hello world!")
int main()
{
	Print;  //预处理时会被替换为 printf("hello world!");
	return 0;
}

3、宏函数:我还可以用宏来定义函数,因为宏定义也可以带参数

例如:

#include"stdio.h"
#define Print(str) printf("%s",str)
int main()
{
	Print("这是一个只有一条语句的宏函数!");
    //预处理时会被替换为 printf("%s","这是一个只有一条语句的宏函数!")
	return 0;
}

运算符优先级问题:

#define SQUARE_SUM(x,y) x*x+y*y
#include <stdio.h>
 
int main()
{
    int i = 1,j = 2,k ;
    k = SQUARE_SUM(i+1,j);
    printf("%d",k);
    return 0;
}

很多人可能会这样算:2*2+2*2=8,这样其实是错误的。原因是程序只是做了替换,也就是1+1*1+1+2*2=7

如果想要结果为8的话应该这样写:


#define SQUARE_SUM(x,y) (x)*(x)+(y)*(y) //注意这里的括号!!
#include <stdio.h>
 
int main()
{
    int i = 1,j = 2,k ;
    k = SQUARE_SUM(i+1,j);
    printf("%d",k);
    return 0;
}

四、条件编译:

条件编译命令最常见的形式为:

#ifdef 标识符
程序段 1
#else
程序段 2
#endif

它的作用是:当标识符已经被定义过(一般是用#define 命令定义),则对程序段 1 进行编译,否则编译程序段 2。 其中#else 部分也可以没有,即:

#ifdef
程序段 1
#endif

条件编译规则如下:


#ifdef   MAVIS       //如果定义了MAVIS,则执行下面的条件
    {
        ;
    }
#else                //如果未定义了MAVIS,则执行下面的条件  //#else 可省略
    {
        ;
    }
#endif
 
// 备注: C只编译符合条件的模块;
 
// 例如:
 
#ifdef CUSTOMIZED
    // thread 0
    {
        "Dsp1-thread0",     // thread name
        Alg_init,      // init function
        Alg_prep,      // pre-process function
        Alg_proc,      // main process function
        Alg_deinit,    // de-init function
        TRUE,               // need output buffer?
    },
 
#endif
    // thread 1, 
    {
       "",//Dsp1-thread1",      // thread name
        NULL,               // init function
        NULL,               // pre-process function
        NULL,               // main process function
        NULL,               // de-init function
        FALSE,              // need output buffer
    }

运用#if  #elif  #elif #else #endif 来进行条件编译:


#if defined (IBMPC)    //可以用 #if defined(VAX) 代替 #ifndef VAX 和#elif 一起使用;
    #include "ibmpc.h"
#elif defined (VAX)
    #include "vax.h"
#elif defined (MAC)
    #include "mac.h"
#else
    #include "general.h"
#endif

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值