C语言编程的一些巧妙方法。

来源:本站
导读:目前正在解读《C语言编程的一些巧妙方法。》的相关信息,《C语言编程的一些巧妙方法。》是由用户自行发布的知识型内容!下面请观看由(电工技术网 - www.9ddd.net)用户发布《C语言编程的一些巧妙方法。》的详细说明。
简介:本文介绍了C语言编程时的一些简单、巧妙方法。

一、学习头文件包含巧妙用法

当一个头文件被多个C文件包含,且该头文件中定义了这些C文件的公共变量,则在编译的时候会出现重复定义,导致编译通不过,通常我们会采用如下两种做法来解决上述问题。

(为了让问题表述得更清楚,我们假设两个C文件C1,C2,C3,一个头文件H1,C1,C2,C3有两个公共变量V1和V2)

1、 在C1文件中定义变量V1和V2,在C2和C3文件中对V1,V2用extern声明;

2、 在C1文件中定义变量V1和V2,在H1中对V1,V2用extern声明,然后在C2和C3文件中包含H1;

很显然,以上两种方法都要对V1和V2书写至少两次,一次定义,一次外部声明,且不是在同一文件下,这样不利于管理和修改,有没有一种方法可以让这些公用的变量放在一个文件里,且只要书写一次呢?

首先我们将要用到的公共变量全部书写到com.h文件中,每一个变量在定义前加一个符号EXT_,当该头文件被main.c函数包含时,定义EXT_为空,表示com.h中的变量在main.c中被定义,当被其它文件包含时,定义EXT_为extern,表示外部声明,如:

Com.h文件:

//避免重复定义

#ifdef root

#define EXT_

#else

#define EXT_ extern

#endif

//全局变量

EXT_ u8 variable1; //该变量在三个C文件中都要用到

Main.c

#define root //在包含com.h前定义root

#include "com.h"

二、用结构体的方式来定义总线或外设地址

当一个整体包含不同类型的多个成员时,通常用结构体来定义结构体变量,这样内存会将这些变量按照递增的方式分配到相邻的地址(不对齐的地方会有填充),按“结构体名.成员名”的方式访问结构体内的成员,这是访问结构体变量的方式;但是还有一种指向结构体变量的指针,它可以将某个地址转换成该结构体类型的指针,比如寄存器的定义:

(以下是摘自STM32固件函数库,关于GPIO的定义)

typedef struct

{

vu32 CRL; //0

vu32 CRH; //偏移量4

vu32 IDR; //偏移量8

vu32 ODR;

vu32 BSRR;

vu32 BRR;

vu32 LCKR;

} GPIO_TypeDef;

#define GPIOA_BASE ((u32)0x40010800) //GPIOA的基地址为0x40010800

#define GPIOA (GPIO_TypeDef *) GPIOA_BASE; //强制类型转换为GPIO_TypeDef类型的指针

这样在操作GPIOA的寄存器时只要这样写就可以了

读: X="GPIOA-">CRL; 写:GPIOA->CRL=X;

或 读: X=(*GPIOA).CRL; 写:(*GPIOA).CRL =X;

当然,要达到上述目的也可以采用如下方式

#define GPIOA_ CRL 0x40010800

#define GPIOA_ CRH 0x40010804

#define GPIOA_ IDR 0x40010808

#define GPIOA_ ODR 0x4001080C

#define GPIOA_ BSSR 0x40010810

#define GPIOA_ LCKR 0x40010814

很明显,第一种书写方式更加正规化,且当定义多个GPIO时,只要将其它GPIO的基地址强制转换为该结构类型的指针即可。

再来看看一个定义外部总线的例子

typedef struct

{

vu8 CH375_DATA;

vu8 CH375_CMD; //偏移量1

} CH375_TypeDef;

#define CH375 ((CH375_TypeDef *) 0x6c000000)

CH375-> CH375_DATA=data; //往0x6c000000地址处写数据

CH375-> CH375_CMD=cmd; //往0x6c000001地址处写命令

怎么样,是不是方便多了。重要的是代码的观赏和可读性。

三、用枚举数据类型来定义特定的状态

在实际问题中,有些变量的取值被限定在一个有限的范围内。例如,一个函数在操作过程中会返回几个特定的状态:操作成功,操作失败,忙,等等。如果我们直接在函数里用0,1和2来表示这三种状态,有时偶尔会出现数值与实际状态对不上号的情况,造成置状态和判断状态错误,那么我们可以在程序里用宏或者枚举来事先定义好这些状态。

如:用宏定义:

#define Sucess 0

#define Failure 1

#define Busy 2

用枚举

typedef enum { Sucess = 0, Failure , Busy } FlagStatus;

四、用共用体类型定义共享内存空间

共用体类型定义的数据是将多个成员共享同一内存空间,该空间的大小为最大成员的大小,其用法与结构体完全相同,但值得注意的是不能同时引用多个成员,在某一时刻只能使用其中之一成员。

在程序中如果全局变量比较多,包含几个结构和数组,如果这些全部定义的话势必会占大量的内存,有可能还会导致单片机内存不够,如果能让几个不同时用到的数组和结构变量共享一段内存,则能省出很多的内存空间。

比如以下输入输出若不同时进行,则可以共享同一段内存空间

union {

struct {

unsigned char Flag;

unsigned char Type;

unsigned char State;

unsigned long DataLen;

unsigned char Buffer[64];

}DataOut;

struct {

unsigned char Flag;

unsigned char Type;

unsigned char State;

unsigned long DataLen;

unsigned char Buffer[64];

} DataIn;

} BOC;

提醒:《C语言编程的一些巧妙方法。》最后刷新时间 2024-03-14 01:03:23,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《C语言编程的一些巧妙方法。》该内容的真实性请自行鉴别。