单片机开发工具篇:(五)keil 中常用的 C 语言(简述),stdnt.h、位操作符、条件编译和宏定义、extern 声明、typedef、结构体、指针 - 实践

上一篇下一篇
KEIL 与 AC5 和 AC6STM32CubeMX 的使用

keil 中常用的 C 语言

1)stdint.h

stdint.h 是从 C99 中引进的一个标准 C 库的文件(属于是官方的文件,大部分的厂商都会沿用这个)。

路径:D:\ruanjian\keil5-MDK-ARM\ARM\ARM_Compiler_5.06u7\include\stdint.h

主要内容是:一些宏定义,以及类型别名的重定义

/* 7.18.1.1 */
/* exact-width signed integer types */
typedef   signed          char int8_t;
typedef   signed short     int int16_t;
typedef   signed           int int32_t;
typedef   signed       __INT64 int64_t;
/* exact-width unsigned integer types */
typedef unsigned          char uint8_t;
typedef unsigned short     int uint16_t;
typedef unsigned           int uint32_t;
typedef unsigned       __INT64 uint64_t;

上面代码的间隔或许会误导人,比如第一行,其实是将 signed char 重定义成 int8_t ,后面以此类推。

2)位操作符

位从 0 开始,位 6 就是从右往左数第七个

10 进制和 2 进制互相转换有口诀:8421。每 4 位 2 进制 1111 就是 15 ,且 8(1000)、4(0100)、2(0010)、1(0001)

10 进制和 2 进制的互换明白之后,转成 16 进制就不是问题。

运算符含义运算符含义
&按位与~按位取反
|按位或<<左移
^按位异或>>右移

【注意】异或:相同为 0 ,不同为 1 ( 0 和任何数异或都不变,和 1 异或可达到位翻转的效果)。

给某个寄存器或变量某个位赋值(将位 6 赋值为 1 ):

uint8_t temp=0;
temp &= 0XBF; 		// 方式1.1, 0XBF = 1011 1111
temp &= ~(1<<6); 	// 方式1.2, ~(1<<6) = 1011 1111
temp |= 0X40; 		// 方式2.1, 0X40 = 0100 0000
temp |= 1<<6; 		// 方式2.2, 1<<6 = 0100 0000

3)条件编译和宏定义

① 条件编译

指令作用
#if编译预处理条件指令,类似 if
#ifdef判断某个宏是否已被定义
#ifndef判断某个宏是否未被定义
#elif若前面的条件不满足,则判定新的条件,类似 else if
#else若前面的条件不满足,则执行后面的语句,类似 else
#endif#if、#ifdef、#ifndef 的结束标志

头文件定义示例:

#ifndef _LED_H
#define _LED H
#include "**.h"
code
#endif

代码条件编译:

#if SYS_SUPPORT_OS
code
#endif

② 宏定义

有两种,分别是 常量宏定义 与 函数宏定义 。

  • 常量宏定义

    #define 常量名 常量值
    // 例如:#define PI 3.1415926

    宏名通常用大写字母,以区别于变量。末尾不加分号,否则分号会被替换到代码中导致错误。

  • 函数宏定义:可以通过带参数宏定义来定义函数

    #define 宏名(参数列表) 替换文本
    // 例如:#define MAX(a, b)  ((a)>(b)?(a):(b))  // 取最大值

    参数和整体表达式需用括号包裹,避免运算符优先级错误。#define ADD(a,b) a + b(×)。

4)extern 声明

放在函数/变量前,表示此函数/变量在其他文件定义,以便本文件引用。

示例:

extern uint8_t temp;
extern void delay_ms(uint32_t nus);

声明时不可赋值,即 extern uint8_t temp=1; (×)

5)typedef

用于为现有数据类型创建 别名(alias),从而简化复杂类型的声明、提高代码可读性和可维护性。

基本语法:

typedef 原始类型 别名;

示例:

// 基本类型别名
typedef unsigned int uint32;  // 将 unsigned int 重命名为 uint32
uint32 a = 10;                // 等价于 unsigned int a = 10;
//结构体类型简化
typedef struct {
int x;
int y;
} Point;  // Point现在是结构体类型别名
Point p1;  // 直接使用别名声明变量
//指针类型简化
typedef int* IntPtr;       // 将int指针类型重命名为IntPtr
IntPtr p = &a;             // 等价于 int* p = &a;
//数组类型简化
typedef int IntArray[10];  // 将包含10个int的数组类型重命名为IntArray
IntArray arr;              // 等价于 int arr[10];
//...等等

6)结构体

定义语句:

//第一种写法:
struct 结构体名
{
成员列表;
...
}实例列表(可选);
//第二种写法:
struct 结构体名
{
成员列表;
...
};
struct 结构体名 实例1,实例2;

上述代码中,实例列表就是这个结构体的实例。

例如:

struct student
{
uint_8 age;
uint_8 sorce;
...
} stu1,stu2;

其中 stu1stu2 就是实例,可以通过 . 来访问元素:stu1.agestu2.sorce

如果使用 typedef 重定义的话,则是:

typedef struct
{
成员列表;
...
}结构体名;
结构体名 实例1,实例2;  // 就不需要在前面写 struct 了

注意:结构体指针使用 -> 来访问元素(和C++一样)。

7)指针

C++ 那里的笔记仔细总结过了,这里就不再解释了。


posted @ 2025-11-16 11:12  yangykaifa  阅读(13)  评论(0)    收藏  举报