STM32之C语言基础复习

Posted Love小羽

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32之C语言基础复习相关的知识,希望对你有一定的参考价值。

目录

一、宏定义

二、条件编译

三、extern声明

四、类型别名(typedef)

1、类型别名应用

五、结构体

1、应用举例(ST源码,使用类型别名)

六、指针

1、指针使用的二大最常见问题

七、位操作 

 1、如何给寄存器某个位赋值


一、宏定义

宏定义可以:提高效率、可读性、易改性、核心是替换

1、不带参数的宏定义

#define 标识符 字符串

标识符:宏定义的名字 (建议大写)
字符串:常数、表达式、格式串等

宏定义是一个临时的符号,是不占用内存的,属于预处理程序中代码
例如:#define PI 3.14159

2、带参数的宏定义

#define LED1(X) do x?\\
    A:\\
    B;\\
while(0)

建议使用do.....while(0)来构造宏定义,这样不会受到大括号、分号、运算符优先级等的影响

二、条件编译

让编译器只对满足条件的代码进行编译,不满足条件的不参与编译

 举例:头文件的条件编译结构

#ifndef _LED_H
#define _LED_H
#include "./SYSTEM/sys/sys.h"
code
#endif

三、extern声明

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

extern uint16_t g_usart_rx_sta;
extern void delay_us(uint32_t nus);

g_usart_rx_sta:一个全局变量
delay_us:      一个函数

extern的作用是:告诉编译器,在这个文件中,我要调用这个变量/函数,你需要去其他的文件中找到这个变量/函数

四、类型别名(typedef)

为现有数据类型创建一个新的名字,或称为类型别名,用来简化变量的定义

typedef   现有类型    新名字

typedef unsigned char   uint8_t;
typedef unsigned int    uint16_t;

1、类型别名应用

(1)定义一个结构体

Struct GPIO_TypeDef           //定义一个结构体的类型

    _IO uint32_t CRL;
    _IO uint32_t CRH;
    ...
;

Struct GPIO_TypeDef gpiox     //定义一个结构体的变量名

 (2)用类型别名定义一个结构体

typedef struct          //定义一个结构体的类型

    _IO uint32_t CRL;
    _IO uint32_t CRH;
    ...
GPIO_TypeDef;

GPIO_TypeDef gpiox      //定义一个结构体的变量名

五、结构体

由若干基本数据类型集合组成的一种自定义数据类型,也叫聚合类型

struct 结构体名

    成员列表;
变量名列表(可选);
struct student

    char   *name;    //姓名
    int    num;      //学号
    int    age;      //年龄
    char   group;    //所在的学习小组
    float  score;    //成绩
stu1,stu2;

stu1.name  = "张三";
stu1.num   = 1;
stu1.age   = 18;
stu1.group = 'A';
stu1.score = 80.9;

1、应用举例(ST源码,使用类型别名)

typedef struct

    uint32_t Pin;      //引脚号
    uint32_t Mode;     //工作模式
    uint32_t Pull;     //上下拉
    uint32_t Speed;    //IO速度
GPIO_InitTypeDef;     //类型别名

六、指针

指针就是内存的地址

指针变量是保存了指针的变量

类型名  * 指针变量名

char *p_str = "This is a test!";   ----->指向字符串的首地址,也就是"T"

*p_str: 取p_str变量的值             ----->结果应为"T"

&p_str: 取p_str变量的地址           ----->应是p_str变量自身的地址

举例说明:左侧各数值均得多少

 结果:

*p_buf     = 1

p_buf[0]  = 1

p_buf[1]  = 3

*p_buf++  指的是递增

*p_buf    = 3

p_buf[0] = 3

1、指针使用的二大最常见问题

(1)未分配(申请)内存就用

(2)越界使用

七、位操作 

 1、如何给寄存器某个位赋值

C语言复习之猜数小游戏

1.声明

当前内容主要为本人复习C语言之用,涉及到一个小的猜数小游戏的demo

主要涉及

  1. 伪随机数的产生
  2. 结构体传递

2.demo

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

/*
猜数字游戏完成
2021/05/01
*/
typedef struct
{
    int level;
    char *levelPrompt;
    int levelCanInputNum;
} GameLevel; // 定义一个游戏等级的结构

typedef struct {
    int guessNum;
    int (*getRandom)(int);
    int userCount;
    int **inputRecord;
    GameLevel glevel;
} GuessGame; // 定义一个猜数的结构

// 主要获取当前产生的随机数,用于猜数,按照级别来生成
int getRandom(int level){
    srand(time(NULL));
    int weed=0;
    switch(level)
    {
        case 1:
            weed=9;
            break;
        case 2:
            weed=99;
            break;
        case 3:
            weed=999;
            break;
        default:
            weed=9;
            break;
    }
    int guessNum=1+rand()%weed;
    return guessNum;
}

// 通过级别方式获取游戏级别的结构
GameLevel getGameLevel(int level){
    GameLevel glevel;
    glevel.level=level;
    switch(level)
    {
        case 1:
            glevel.levelPrompt="1到10";
            glevel.levelCanInputNum=3;
            break;
        case 2:
            glevel.levelPrompt="1到100";
            glevel.levelCanInputNum=5;
            break;
        case 3:
            glevel.levelPrompt="1到1000";
            glevel.levelCanInputNum=10;
            break;
        default:
            glevel.levelPrompt="1到10";
            glevel.levelCanInputNum=3;
            break;
    }
    return glevel;
}

void printInputRecord(int userCount,int *inputNums){
    if(userCount==1)
    {
        puts("一次就正确");
    }else
    {
        puts("当前输入的内容如下");
        puts("******************");
        for(int i=0;i<userCount;i++)
        {
            printf("第%d次,输入为:%d\\n",(i+1),inputNums[i]);
        }
        puts("******************");
    }
}

int promptCurrentResult(int inputNum,int guessNum){
    int isSuccess=0;
    if(guessNum==inputNum)
    {
        puts("猜对了");
        isSuccess=1;
    }else if(inputNum>guessNum){
        puts("再小点");
    }else
    {
        puts("再大点");
    }
    return isSuccess;
}

int main()
{
    int guessNum,inputNum;
    int userCount=0;
    int totalInputNum;
    puts("请输入猜字游戏级别:");
    int level=1;
    scanf("%d",&level);
    guessNum=getRandom(level);
    GameLevel glevel=getGameLevel(level);
    totalInputNum=glevel.levelCanInputNum;
    int inputNums[totalInputNum];
    while(1)
    {
        printf("请输入猜的数字(%s),还有%d次机会\\n",glevel.levelPrompt,(totalInputNum-userCount));
        scanf("%d",&inputNum);
        // record current input number
        inputNums[userCount++]=inputNum;
        if(promptCurrentResult(inputNum, guessNum)){
            break;
        }
        if(userCount>=totalInputNum)
        {
            printf("%d次机会用完,答案是:%d\\n",totalInputNum,guessNum);
            break;
        }

    }

    printInputRecord(userCount, inputNums);

    return 0;
}

3.测试

在这里插入图片描述

测试成功!

以上是关于STM32之C语言基础复习的主要内容,如果未能解决你的问题,请参考以下文章

stm32开发,C语言, 跳转执行中断函数,会保存原来函数的局部变量吗

STM32中常用的C语言知识点总结!

用 C 语言 (STM32F4) 估计剩余的可用 RAM

c语言volatile是啥意思

STM32单片用什么编程?如何学习STM32单片机开发

C语言在STM32中的内存分配