关于学习STM32的C语言的知识

发布于:2025-04-20 ⋅ 阅读:(13) ⋅ 点赞:(0)
  • 数据类型

关键字 位数 表示范围 stdint关键字
char 8
-128 ~ 127
int8_t
unsigned char 8
0 ~ 255
uint8_t
short 16
-32768 ~ 32767
int16_t
unsigned short 16
0 ~ 65535
uint16_t
int 32
-2147483648 ~ 2147483647
int32_t
unsigned int 32
0 ~ 429496729
uint32_t
long 32
-2147483648 ~ 2147483647
unsigned long 32
0 ~ 4294967295
long long 64
-(2^64)/2 ~ (2^64)/2-1
int64_t
unsigned long long 64
0 ~ (2^64)-1
uint64_t
float 32
-3.4e38 ~ 3.4e38
double 64
-1.7e308 ~ 1.7e308
  • 宏定义

        定义:在C语言中,宏定义是一种预处理指令,用于将一个标识符(宏名)替换为指定的字符串(常数、表达式、格式串等)。这个过程称为“宏展开”宏替换。宏定义是通过使用 #define 预处理命令来完成的。

格式:# define 宏名 字符串

作用:

  • 提升易读性:比如 # define HIGH 1
  • 便于批量修改:比如 # define PIN 5

应用场景:

  • 定义一个常量

# define PI 3.14159

  • 宏函数:

C语言的宏定义还支持一些更复杂的操作,如算术运算和逻辑运算。例如:

#define area(x)  (x * x)

 在这个例子中,我们定义了一个名为 AREA 的宏,它接受一个参数 x ,并返回 x * x 的结果。当程序中出现area(5) 时,它会被替换为 (5 * 5)

在stm32中经常和条件运算符结合使用:

#define LED(X) do{x?A:B
                       }while(0);
                

上面代码中:do-while 语句 经常在stm32中使用。

  • typedef

定义:通过使用 typedef ,可以为现有的 数据类型 创建一个新的名称,这样可以使代码更加简洁、易读。

应用场景:

typedef 可以用于为基本数据类型、结构体、联合体(共用体)等定义别名。

  • 可以定义一个名为 SIZE 的类型,该类型为 unsigned int 类型:

typedef unsigned int SIZE;

SIZE a = 10;

a = 20;

  •  可以使用 IntPtr 作为指向整数的指针类型的别名:

typedef int* IntPtr;

IntPtr p = malloc(sizeof(int));

*p = 10;

teypdef 与 宏定义的区别(记住):

  • 宏定义新名字左边,typedef在右边;
  • 宏定义不需要分号,typedef需要分号;
  • typedef只能替换数据类型,宏定义一切可以替换;
  • typedef具有检查的功能,判断替换的是不是数据类型。
  •  条件编译

与C存在区别:需要加上 “# ”号;#elif(C中是elseif);endif 结束

        C语言中的条件编译主要通过 #if 、#ifdef #ifndef #else #elif #endif 等预处理指令来实现。这些指令可以在代码的任何位置使用,以根据特定的条件来控制代码的编译。

例子1:(#if - #elif - #endif)

#if 表达式1
    // 如果表达式1为真,则编译下面的代码
#elif 表达式2
    // 如果表达式1为假且表达式2为真,则编译下面的代码
#else
    // 如果未定表达式1和表达式2都未执行,则编译此处的代码
#endif

例子2:(# ifdef 和 # ifndef) 

#ifdef 宏名
    //如果宏已经定义,则编译下面的代码
#endif
#ifndef 宏名
    // 如果宏未定义,则编译下面的代码
#endif

常用于定义一个.h的文件中先声明是否进行宏定义。

  • 结构体

struct 结构体名 {
        数据类型 成员名1;
        数据类型 成员名2;
        ...
        数据类型 成员名n;
};

举例:在定义结构体后,可以在程序中使用该结构体来声明变量,并为其分配内存空间。

struct Student {
    char gender;
    int age;
    float score;
};
struct Student stu1;

        在上面的例子中,我们定义了一个名为 Student 的结构体类型,它包含三个成员: gender age 和 score 。然后我们声明了一个名为 stu1 的结构体变量,并为其分配了内存空间。

        结构体变量可以用于存储具有不同属性或特征的数据,例如学生的性别、年龄和成绩。结构体中的成员可以通过点运算符( . )来访问,例如 stu1.name 表示访问 stu1 变量的 name 成员。

        此外,C语言还提供了 结构体数组结构体指针 (详见C文章中的结构那章)等用法,以便更灵活地处理和操作结构体数据

  • 枚举 (enum)

应用1:为一组整数值分配有意义的名字

        C语言中的枚举(enum)是一种用户定义的数据类型,它允许你为一组整数值分配有意义的名字。枚举常用于为变量的可能值定义有意义的名称,或者为编译器的内部值分配用户定义的名称。

格式:

 enum 枚举名 {

        常量1 , 常量 2 , ...
};

         其中, 枚举名 是你给枚举类型起的名字,而 常量1 常量2 等是该枚举类型的成员名。这些成员名在编译时会被赋予整数值,默认从0开始,每次递增1

举例:

enum Color {
RED=0, GREEN, BLUE
};

        在这个例子中,我们定义了一个名为 Color 的枚举类型,它有三个成员: RED GREEN BLUE 。这三个成员在编译时会被赋予整数值,分别是012。

应用2:限制变量的取值范围。

enum Weekday {
MONDAY=1, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
};

enum Weekday today;
today = MONDAY; // 或者其他有效的枚举值
  • 指针(具体详见C语言篇章中的指针)

定义:C语言中的指针是一种特殊的变量,它存储了一个内存地址,这个地址可以是其他 变量 的地址,也可以是 数组的元素、结构体、函数等类型的地址。通过指针,我们可以间接地访问和操作这些内存地址所指向的内容。

一些C语言指针的例子:

        1.定义并初始化指针

int x = 10;

int *p = &x; // p指向变量x的地址

        2.通过指针访问变量

int value = *p;  // 获取p所指向的整数值,即x的值

*p = 20;  // 修改p所指向的整数值,即x的值

         3. 指针的算术运算

int arr[5] = {1, 2, 3, 4, 5};

int *ptr = arr; // ptr指向数组的首地址

int i = 0;

for (i = 0; i < 5; i++) {

        printf("%d ", *(ptr + i)); // 输出数组元素的值

}

        4. 动态内存分配: 

int *p = ( int * )malloc(sizeofint ));   // 分配一个整数的内存空间,返回指向该空间的指针p

if (p != NULL) {    //如果内存空间创建成功

        *p = 20;     // 在该内存空间中存储整数值20

        printf("%d\n", *p);     // 输出20

free(p);     // 释放内存空间

}

 但同时也要注意指针的使用可能会导致 内存泄漏野指针 等问题,需要谨慎处理。


网站公告

今日签到

点亮在社区的每一天
去签到