STM32的GPIO输入和输出函数详解

系列文章目录

STM32单片机系列专栏

C语言术语和结构总结专栏

文章目录

1. GPIO模式

2. GPIO输出

2.1 RCC

2.2 GPIO

3. 代码示例

3.1 RCC时钟

3.2 GPIO初始化

3.3 GPIO输出函数

3.4 推挽输出和开漏输出

4. GPIO输入

4.1 输入模式

4.2 数据读取函数

5. C语言语法


1. GPIO模式

GPIO是微控制器中最基本也是最灵活的功能之一,其可以被配置为输入或输出模式,以及许多其他特殊功能模式。通过配置GPIO的端口配置寄存器,端口可以配置成以下8种模式:

模式名称类型描述
浮空输入浮空输入引脚没有内部或外部上拉或下拉,其电平未定义,通常不建议使用
上拉输入上拉输入引脚内部上拉至VDD,外部信号低于VDD时,检测到低电平
下拉输入下拉输入引脚内部下拉至VSS,外部信号高于VSS时,检测到高电平
模拟输入模拟输入GPIO未锁定,引脚直接连接到内部ADC
开漏输出开漏输出引脚以开漏模式工作,高电平时为高阻态,低电平时连接到VSS
推挽输出推挽输出引脚以推挽模式工作,高电平时连接到VDD,低电平时连接到VSS
复用开漏输出复用开漏输出用于复用功能的开漏输出,高电平时为高阻态,低电平时连接到VSS
复用推挽输出复用推挽输出用于复用功能的推挽输出,高电平时连接到VDD,低电平时连接到VSS

模式分类:

  • 输入模式(Input):引脚被配置为输入,用来读取外部信号的状态。
  • 输出模式(Output):引脚被配置为输出,可以驱动外部设备或显示设备状态。

类型分类:

  • 推挽输出(Push-pull):可以在两种状态之间切换,要么连接到VDD(高电平),要么连接到VSS(低电平)。
  • 开漏输出(Open-drain):只能连接到VSS(低电平),而高电平状态需要外部拉高。

GPIO配置说明

  • 浮空输入(Floating input):引脚没有内部或外部的上拉或下拉电阻,状态由外部电路决定。
  • 上拉输入(Pull-up input):引脚内部连接有上拉电阻,如果外部电路没有连接,它将读取为高电平。
  • 下拉输入(Pull-down input):引脚内部连接有下拉电阻,如果外部电路没有连接,它将读取为低电平。
  • 模拟输入(Analog input):GPIO以模拟方式工作,可以直接连接到内部ADC(模拟到数字转换器)。
  • 开漏输出(Open-drain output):引脚在激活时连接到VSS,非激活时不连接(悬空)。常用于需要外部拉高的应用场合。
  • 推挽输出(Push-pull output):引脚可以输出高电平(连接到VDD)或低电平(连接到VSS)。
  • 复用开漏输出(Alternate function open-drain output):开漏输出,但是引脚被配置为特殊功能,例如I2C通信。
  • 复用推挽输出(Alternate function push-pull output):推挽输出,但是引脚被配置为特殊功能,例如PWM输出。

2. GPIO输出

操作STM32的GPIO一共有三个步骤:

  1. 使用RCC开启GPIO的时钟
  2. 使用GPIO_Init函数初始化GPIO
  3. 使用输出或者输入函数控制GPIO

2.1 RCC

首先打开一个新建好的工程文件,如果不知道怎么建立工程文件,可以看下面这篇文章:

使用Keil MDK创建STM32标准库工程

之后在Library中找到rcc.h文件(这里全程使用vscode去操作,如果不知道怎么实现Keil和VSCode协同开发STM32程序,可以查看下面这篇教程:

Keil和VSCode协同开发STM32程序

在rcc.h文件中拖到最下面,这里一般都是所有库函数的声明,这里最常用的就是这三个函数:

void RCC_AHBPeriphClockCmd:外设时钟控制

接着选择函数名,右键并选择转到定义(这里需要先进行一次编译,否则可能无法跳转) ,之后会来到.c文件的函数定义,下面解释一下这个函数:

// 函数定义:控制特定AHB外设的时钟。
// RCC_AHBPeriph:要配置的AHB外设。
// NewState:指定外设时钟的新状态,ENABLE(使能) 或 DISABLE(失能)。
void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState)
{// 确保输入参数RCC_AHBPeriph是预定义的有效外设。assert_param(IS_RCC_AHB_PERIPH(RCC_AHBPeriph));// 确保输入的NewState是有效的功能状态(ENABLE 或 DISABLE)。assert_param(IS_FUNCTIONAL_STATE(NewState));// 如果NewState不是DISABLE(即是ENABLE),执行以下代码。if (NewState != DISABLE){// 通过逻辑或运算将对应的位设置为1,来使能(开启)外设的时钟。RCC->AHBENR |= RCC_AHBPeriph;}// 如果NewState是DISABLE,执行以下代码。else{// 通过逻辑与运算与对应位的否定值运算,将对应的位设置为0,来禁能(关闭)外设的时钟。RCC->AHBENR &= ~RCC_AHBPeriph;}
}

2.2 GPIO

下面看一下GPIO.h的文件,在Library中找到GPIO.h文件,也是拖到最后,这里可以看到常用的函数。

void GPIO_DeInit(GPIO_TypeDef* GPIOx);
void GPIO_AFIODeInit(void);
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct);
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);

void GPIO_DeInit(GPIO_TypeDef* GPIOx);
功能:将指定GPIO端口的所有配置重置为默认值。
参数:GPIOx:要重置的GPIO端口,例如GPIOA、GPIOB等。
说明:这个函数通常用于在重新配置(复位)GPIO端口之前清除端口的当前配置。


void GPIO_AFIODeInit(void);
功能:将AFIO(Alternate Function IO)模块的所有配置重置(复位)为默认值。
说明:这个函数通常用于清除所有GPIO端口的复用功能配置。


void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
功能:用结构体的参数初始化指定GPIO端口的引脚。
参数:

  • GPIOx:要初始化的GPIO端口,例如GPIOA、GPIOB等。
  • GPIO_InitStruct:包含了初始化配置的结构体指针,如引脚模式、输出类型、输出速度等。

说明:这个函数用于配置GPIO引脚的各种属性,例如输入/输出模式、输出类型、输出速度等。


void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct);
功能:将给定的GPIO_InitTypeDef结构体初始化为默认值。
参数:GPIO_InitStruct:要初始化的GPIO_InitTypeDef结构体指针。
说明:这个函数用于在配置GPIO引脚之前,将相关的结构体初始化为默认值。


uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);

功能:读取指定GPIO端口指定引脚的输入状态。
参数:

  • GPIOx:要读取的GPIO端口,例如GPIOA、GPIOB等。
  • GPIO_Pin:要读取的引脚,可以是单个引脚或多个引脚的按位或组合。

返回值:引脚的输入状态,0/1。或者GPIO端口的输入状态,每个引脚的状态对应一个位。


void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
功能:将指定GPIO端口指定引脚的输出状态设置为高电平。
参数:

  • GPIOx:要设置的GPIO端口,例如GPIOA、GPIOB等。
  • GPIO_Pin:要设置的引脚,可以是单个引脚或多个引脚的按位或组合。

void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
功能:将指定GPIO端口指定引脚的输出状态设置为低电平。
参数:

  • GPIOx:要重置的GPIO端口,例如GPIOA、GPIOB等。
  • GPIO_Pin:要重置的引脚,可以是单个引脚或多个引脚的按位或组合。

void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);
功能:将指定GPIO端口指定引脚的输出状态设置为指定的电平。
参数:

  • GPIOx:要写入的GPIO端口,例如GPIOA、GPIOB等。
  • GPIO_Pin:要写入的引脚,可以是单个引脚或多个引脚的按位或组合。
  • BitVal:要设置的电平,可以是Bit_RESET(低电平)或Bit_SET(高电平)。

void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);
功能:设置指定GPIO端口的输出状态。
参数:

  • GPIOx:要写入的GPIO端口,例如GPIOA、GPIOB等。
  • PortVal:要设置的输出值,每个引脚的状态对应一个位,0表示低电平,1表示高电平。

3. 代码示例

这里使用最基础的led灯来解释代码功能

3.1 RCC时钟

main.c文件中,首先调用RCC中的APB2外设时钟控制函数,首先和刚才一样,在RCC.h找到函数名, RCC_APB2PeriphClockCmd, 复制到main中,接着右键函数转到定义,根据注释中的提示,因为点亮的是PA0的LED,所以选择 RCC_APB2Periph_GPIOA,将其放到第一个参数,第二个参数选择ENABLE, 这样时钟就开启了。

 

3.2 GPIO初始化

接着调用GPIO的初始化函数,在GPIO.h中找到 GPIO_Init 函数,跳转到定义,和rcc类似根据注释中的提示,第一个参数选择GPIOA, 第二个参数是一个结构体

先把结构体复制到GPIO_Init上面,起名为:GPIO_InitStructure, 这个结构体相当于一个局部变量,然后将结构体的成员都列出来,如下所示:

	GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = ;GPIO_InitStructure.GPIO_Mode = ;GPIO_InitStructure.GPIO_Speed = ;GPIO_Init()

接下来就是如何根据标准库文件来配置函数,以GPIO_Mode为例, 接下来会详细到每一个操作,之后这些操作会省略。

  • 首先右键 GPIO_Mode转到定义

  • 根据提示,我们选择GPIOMode_TypeDef,接着按ctrl+f 搜索,在下面找到定义方式,这里有GPIO的八种工作模式。

  • GPIO_Mode_AIN (0x0):模拟输入模式(Analog Input Mode)
  • GPIO_Mode_IN_FLOATING (0x04):浮空输入模式(Floating Input Mode)
  • GPIO_Mode_IPD (0x28):输入下拉模式(Input Pull-Down Mode)
  • GPIO_Mode_IPU (0x48):输入上拉模式(Input Pull-Up Mode)
  • GPIO_Mode_Out_OD (0x14):开漏输出模式(Open-Drain Output Mode)
  • GPIO_Mode_Out_PP (0x10):推挽输出模式(Push-Pull Output Mode)
  • GPIO_Mode_AF_OD (0x1C):复用开漏输出模式(Alternate Function Open-Drain Mode)
  • GPIO_Mode_AF_PP (0x18):复用推挽

因为这里是为了实现LED功能,所以使用GPIO_Mode_Out_PP,将其复制到GPIO_Mode后面。

接着是GPIO_Pin,同样的操作,转到定义,这里很简单,选择GPIO_Pin_0即可。

  • 如果要使用多个A引脚,例如多个led灯,直接在后面加上即可,每个定义之间用 | 隔开。

最后是GPIO_Speed,转到定义以后,按ctrl+f 搜索,如图所示下一个就是函数说明,这里选择GPIO_Speed_50MHz,将其复制到GPIO_Speed后面。

最后,将完成配置的结构体的变量名:GPIO_InitStructure,复制到GPIO_Init中即可完成GPIO的初始化配置。

此时,main.c中的代码如下:

#include "stm32f10x.h"                  // Device headerint main(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);while (1){}
}

3.3 GPIO输出函数

完成GPIO的初始化之后,就可以使用GPIO的输出函数了,四个输出函数为(前面已经解释):

void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
//将指定GPIO端口指定引脚的输出状态设置为高电平。
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
//将指定GPIO端口指定引脚的输出状态设置为低电平。
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);
//将指定GPIO端口指定引脚的输出状态设置为指定的电平。
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);
//设置指定GPIO端口的输出状态。

GPIO_ResetBits

我们选择低电平输出,所以使用 GPIO_ResetBits,和前面的操作一样,可以转到定义查看注释说明,因为led灯使用A0引脚,所以代码为:

	GPIO_ResetBits(GPIOA, GPIO_Pin_0);

此时下载程序到单片机中就可以看到LED灯已经被点亮。(注意这里采用的时led长脚连接负极,短接连接引脚,代表低电平点亮)

GPIO_SetBits

如果换成 GPIO_SetBits,可以发现LED熄灭,因为此时输出为高电平。

GPIO_WriteBit

第三种输出函数:GPIO_WriteBit,这个函数是指定输出类型,比如前面的配置不同改变,多了一个BitAction参数,转到定义,可以发现注释教程中说明了两个方式Bit_RESETBit_SET

Bit_RESET: 清除端口值(置低电平)

Bit_SET: 设置端口值(置高电平)

GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_SET); 此时led点亮。。GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_SET); 此时led熄灭。

目前main.c中的代码如下:

#include "stm32f10x.h"                  // Device headerint main(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_SET);while (1){}
}

这里的GPIO_WriteBit用于LED点亮时,可能会发现一个问题,Bit_SET可以置为高电平,此时LED熄灭,那如果想用基本的0和1来代表高低电平,直接将Bit_SET改为1会出现警告,所以还需要加上强制类型转换,把1和0类型转为BitAction的枚举类型:

GPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction)1);

这就是GPIO输出函数的配置,之后就是你想实现的功能,这些功能就是在后面的while中去实现,并且根据不同的模块和功能添加不同的库,例如实现led连续闪烁,除了修改main.c中的主程序,还需要在工程文件在加入delay.c 和 delay.h 文件。但操作都类似,在.h文件中找到需要使用的标准库函数,转到定义在.c文件中找到函数定义和注释说明。

GPIO_WriteBit

这个函数可以设置指定GPIO端口的输出状态。例如对于多个led的控制。

首先还是转到定义,从注释中可以看到,第一个参数依然是GPIOA, 第二个参数是指定写到输出数据寄存器的值,下面可以看到第二个参数是直接写道GPIO和ODR寄存器里的。

所以可以直接写0x001(十六进制),对应二进制为0000 0000 0000 0001。这16个二进制分别对应PA0 - PA15 一共16个端口,最低位(右边)对应PA0。

此时如果加入延迟函数,就可以实现最基本的led灯流水线

#include "stm32f10x.h"                  // Device headerint main(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);while (1){GPIO_Write(GPIOA, 0x0001); // Set PA0Delay_ms(1000);GPIO_Write(GPIOA, 0x0002); // Set PA1	Delay_ms(1000);GPIO_Write(GPIOA, 0x0004); // Set PA2Delay_ms(1000);}
}

如果设置为低电平触发,可以在参数前加上 ~ ,意思是取反。

3.4 推挽输出和开漏输出

对于推挽输出和开漏输出的驱动问题,还是用刚才led的例子,目前我们使用的是GPIO_Mode_Out_PP (0x10):推挽输出模式。此时将led短脚连接负极,长接连接引脚,代表高电平点亮,这时可以发现程序依然可用,说明在推挽模式下,高低电平都有驱动能力。

如果把端口的模式改为 GPIO_Mode_Out_OD (0x14):开漏输出模式

	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;

此时led还是保持高电平点亮,但程序不起作用,只有当led引脚切换以后,改为低电平点亮时,程序才可以正常运行,这说明开漏输出模式的高电平不具有驱动能力。

所以,推挽输出高低电平都有驱动能力,开漏输出高电平相当于高阻态,没有驱动能力,只有低电平有驱动能力。

4. GPIO输入

4.1 输入模式

GPIO输入的配置和GPIO输出类似,不同的数结构体中 GPIO_InitStructure.GPIO_Mode 不同,这里要使用下面的四种输入模式,例如按键输入使用上拉输入模式(GPIO_Mode_IPU)

GPIO_Mode_AIN (0x0):模拟输入模式(Analog Input Mode)

  • 在这种模式下,GPIO引脚被配置为读取模拟信号,意味着它可以直接与微控制器内部的模拟-数字转换器(ADC)相连。
  • GPIO引脚不会被数字输入缓冲器干扰,这样可以保证模拟信号的准确性和质量。
  • 通常用于传感器信号读取,如温度、压力或湿度传感器。

GPIO_Mode_IN_FLOATING (0x04):浮空输入模式(Floating Input Mode)

  • GPIO引脚配置为数字输入,没有激活内部上拉或下拉电阻,其电平状态取决于外部电路。
  • 如果外部没有提供确定的电平,引脚的状态是未定义的,可能会浮动,因此称为“浮空”。
  • 这种模式适合于外部电路总是会驱动GPIO到一个确定状态,或者外部已经提供了必要的上拉或下拉设置。

GPIO_Mode_IPD (0x28):输入下拉模式(Input Pull-Down Mode)

  • PIO引脚配置为数字输入,并且内部激活了下拉电阻,这会将引脚默认拉至低电平(接地)。
  • 如果外部没有提供信号,引脚将读取为低电平状态;如果外部提供了高电平信号,则会被检测到。
  • 这种模式适用于按钮或开关,其中未激活状态需要确保为低电平。

GPIO_Mode_IPU (0x48):输入上拉模式(Input Pull-Up Mode)

  • GPIO引脚配置为数字输入,并且内部激活了上拉电阻,这会将引脚默认拉至高电平(接VDD或正电源)。
  • 如果外部没有提供信号,引脚将读取为高电平状态;如果外部提供了低电平信号,则会被检测到。
  • 这同样适用于按钮或开关,但在这种情况下,未激活状态需要确保为高电平。

4.2 数据读取函数

还有GPIO数据读取的函数:例如读取按键输入就要用到 GPIO_ReadInputDataBit

uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

  • 功能:此函数用于读取STM32的GPIO端口上的单个输入引脚的状态。这对于检测如按钮按下、限位开关触发等简单的二进制输入非常有用。
  • 参数
    • GPIOx:指向你想要读取的GPIO端口的指针。STM32微控制器有多个GPIO端口,例如GPIOA、GPIOB等,每个都对应不同的物理引脚组。
    • GPIO_Pin:具体的GPIO引脚编号,它是一个16位的值,每一位代表一个特定的引脚。例如,如果你想读取第0位,就会使用GPIO_Pin_0
  • 返回值:返回值是一个8位的无符号整数。如果指定的引脚处于高电平状态,则返回非零值;如果处于低电平,则返回零。

uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);

  • 功能:这个函数读取整个GPIO端口的当前输入数据。这在你需要同时检查一个端口上的多个引脚状态时非常有用。
  • 参数
    • GPIOx:与GPIO_ReadInputDataBit函数中的GPIOx相同,指向要读取的GPIO端口的指针。
  • 返回值:返回值是一个16位的无符号整数。每个比特位代表该端口上对应引脚的输入状态,位值为1表示该引脚处于高电平,位值为0表示处于低电平。

uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

  • 功能:此函数用于读取STM32的GPIO端口上的单个输出引脚的状态。这在你需要确认引脚的当前输出状态,例如,确保一个LED是否被程序正确控制时非常有用。
  • 参数
    • GPIOx:与GPIO_ReadInputDataBit函数中的GPIOx相同,指向你想要读取的GPIO端口的指针。
    • GPIO_Pin:与GPIO_ReadInputDataBit函数中的GPIO_Pin相同,表示特定的GPIO引脚编号。
  • 返回值:返回值是一个8位的无符号整数。如果指定的引脚正在输出高电平,则返回非零值;如果正在输出低电平,则返回零。

uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);

  • 功能:这个函数读取整个GPIO端口的当前输出数据。当你需要审核或调试一个端口上多个引脚的输出配置时,这个函数非常有用。
  • 参数
    • GPIOx:与GPIO_ReadInputData函数中的GPIOx相同,指向要读取的GPIO端口的指针。
  • 返回值:返回值是一个16位的无符号整数。与GPIO_ReadInputData类似,每个比特位代表该端口上对应引脚的输出状态,位值为1表示该引脚正在输出高电平,位值为0表示正在输出低电平。

5. C语言语法

STM32基于C语言开发,对于这部分,需要有一些C语言的基础知识,例如下面的数据类型,如果对这方面不太了解,可以看下面的C语言系列讲解。

C语言语法和结构总结系列专栏

数据类型位数表示范围stdint定义ST定义
char8-128 ~ 127int8_ts8
unsigned char80 ~ 255uint8_tu8
short16-32768 ~ 32767int16_ts16
unsigned short160 ~ 65535uint16_tu16
int32-2147483648 ~ 2147483647int32_ts32
unsigned int320 ~ 4294967295uint32_tu32
long32-2147483648 ~ 2147483647int32_ts32
unsigned long320 ~ 4294967295uint32_tu32
long long64-(2^64)/2 ~ (2^64)/2-1int64_t
unsigned long long640 ~ (2^64)-1uint64_t
float32-3.4e38 ~ 3.4e38
double64-1.7e308 ~ 1.7e308

接下来对几个关键的语法进行简单说明:

宏定义  #define

用途:用一个字符串代替一个数字,便于理解,防止出错;提取程序中经常出现的参数,便于快速修改。

定义宏定义:

  #define test 123

引用宏定义:

  int a = test;  //等效于int a = 123;

typedef 

用途:将一个比较长的变量类型名换个名字,便于使用,只能用于变量名。
定义typedef:

 typedef unsigned char uint8_t;

引用typedef:

uint8_t a;    //等效于unsigned char a;

结构体  struct
用途:数据打包,不同类型变量的集合
定义结构体变量:因为结构体变量类型较长,所以通常用typedef更改变量类型名

struct{char x; int y; float z;} StructName;

引用结构体成员:

StructName.x = 'T';
StructName.y = 123;
StructName.z = 55.55;
//或者
pStructName->x = 'T'; //pStructName为结构体的地址    
pStructName->y = 123;
pStructName->z = 55.55;

枚举 enum

用途:定义一个取值受限制的整型变量,用于限制变量取值范围;宏定义的集合.
定义枚举变量:因为枚举变量类型较长,所以通常用typedef更改变量类型名

enum{FALSE = 0, TRUE = 1} EnumName;

引用枚举成员:

EnumName = FALSE;
EnumName = TRUE;

这里知识简单说明,如果想要深入学习,可以看下面的C语言系列讲解。

C语言语法和结构总结系列专栏
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/316548.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

为什么很多企业都使用OV SSL证书

我们要了解什么是SSL OV证书 SSL OV证书,即组织验证型SSL证书,它要求证书颁发机构对申请证书的组织进行身份验证,确认组织的真实性后,才会发放证书。这种验证方式提高了安全性,因为它确保了证书背后的实体是真实存在的…

C语言(操作符)1

Hi~!这里是奋斗的小羊,很荣幸各位能阅读我的文章,诚请评论指点,关注收藏,欢迎欢迎~~ 💥个人主页:小羊在奋斗 💥所属专栏:C语言 本系列文章为个人学习笔记&#x…

基于Springboot的点餐平台

基于SpringbootVue的点餐平台的设计与实现 开发语言:Java数据库:MySQL技术:SpringbootMybatis工具:IDEA、Maven、Navicat 系统展示 用户登录 首页展示 菜品信息 菜品资讯 购物车 后台登录 用户管理 菜品分类管理 菜品信息管理 …

【Linux】dlopen: /lib/x86_64-linux-gnu/libm.so.6: version `GLIBC_2.29‘ not found

[30116] Error loading Python lib /tmp/_MEIlvdUu6/libpython3.8.so.1.0: dlopen: /lib/x86_64-linux-gnu/libm.so.6: version GLIBC_2.29 not found (required by /tmp/_MEIlvdUu6/libpython3.8.so.1.0)1 cd到指定路径 cd /usr/local 2 下载 wget http://ftp.gnu.org/gnu/gl…

NXP i.MX8系列平台开发讲解 - 3.10 Linux PCIe资源分配与访问(二)

专栏文章目录传送门:返回专栏目录 目录 1. PCIe BFD 2. PCIe 配置空间 2.1 PCIe 配置空间访问 PCIe I/O访问方法 PCIe MMIO访问方法 3. PCIe BAR相关 4. PCIe Capbility 5. PCIe 操作 本文将重点讲解PCIe的资源访问相关内容,对于PCIe资源访问是从…

设计不外流,保护创意的同时锁住图纸安全!

在设计行业中,图纸和创意文稿的安全至关重要,因为它们体现了企业的创新能力和核心竞争力。华企盾DSC数据防泄密系统提供了一系列功能,可以有效地保护这些珍贵的设计和文档不被外泄。以下是如何利用华企盾DSC系统保障设计图纸安全的关键措施&a…

【工具】-根源上解决VScode打印输出乱码的问题

目录 1 第一步: 改编译命令,保持一致2 第二步: 更改VScode的编码格式-保持一致 1 第一步: 改编译命令,保持一致 看一下你的控制台的编译的命名后缀,有两个关键的参数,如下图: “-f…

LT9611UXC双端口 MIPI DSI/CSI 转 HDMI2.0,带音频

1. 说明 LT9611UXC 是一款高性能 MIPI DSI/CSI 至 HDMI2.0 转换器。MIPI DSI/CSI 输入具有可配置的单端口或双端口,具有 1 个高速时钟通道和 1~4 个高速数据通道,工作速率最高为 2Gbps/通道,可支持高达 16Gbps 的总带宽。 LT9611UXC 支持突发…

双目深度估计原理立体视觉

双目深度估计原理&立体视觉 0. 写在前面1. 双目估计的大致步骤2. 理想双目系统的深度估计公式推导3. 双目标定公式推导4. 极线校正理论推导 0. 写在前面 双目深度估计是通过两个相机的对同一个点的视差来得到给该点的深度。 标准系统的双目深度估计的公式推导需要满足:1)两…

【算法每日一练】

蛮有意思的的一道题,最后要判断能否成为一种1~n的全排列,我最这样做的: 整个数组先排序一下。假设遍历到了i,那就判断前面b和r的个数,但是有想到了后面可能还会对前面的结果产生影响,所以就抛弃了这个想法…

二、再识VUE-MVVM

一、初识VUE 二、再识VUE-MVVM 三、VUE数据代理 MVVM Vue.js 专注于 MVVM 模型的 ViewModel 层。它通过双向数据绑定把 View 层和 Model 层连接了起来。实际的 DOM 封装和输出格式都被抽象为了 Directives 和 Filters。 ViewModel 一个同步 Model 和 View 的对象。在 Vue.js…

Stable Diffusion基础:ControlNet之线稿成图

今天继续给大家分享Stable Diffusiion的基础能力:ControlNet之线稿成图。 所谓线稿就是由一条条的线段组成的图形,主要用于绘画和设计领域的打底稿、表达构想和预见最终效果。 所谓线稿成图就是利用 Stable Diffusion ControlNet 的能力,依…

极目楚天 共襄星汉 | 同元软控受邀参加2024年中国航天大会

4月23日至26日,2024 年中国航天大会(CSC2024)在湖北省武汉市成功举办。大会由中国宇航学会和中国航天基金会联合主办,以“极目楚天 共襄星汉”为主题,汇聚国内外航天领域知名专家、学者、管理者,深入探讨航…

el-date-picker 禁用时分秒选择(包括禁用下拉框展示)

2024.04.26今天我学习了对el-date-picker进行禁用时分秒, 在使用el-date-picker组件的时候,我们有可能遇到需要把时分秒的时间固定,然后并且不能让他修改: 1714120999296 比如右上角的这个时间,我们要给它固定是‘08:…

C++中auto关键字的用法详解

1.简介 auto作为一个C语言就存在的关键字,在C语言和C之间却有很大区别。 在C语言中auto修饰的变量,是具有自动存储器的局部变量,但因为局部变量默认类别默认是auto修饰导致一直没有人去使用它。 C11中,标准委员会赋予了auto全新…

红魔8/8Pro/8SPro手机升级安卓14版RedMagic9.0系统+降级出厂救砖刷机

红魔8系列手机也终于引来了安卓14系统的更新,该系统为最新的RedMagic9.0,目前属于公测版本,如果你已经升级了官方UI8.0最新版系统,并且拥有公测资格,可以直接在线检测到最新版UI9.0系统。9.0系统目前对比之前的8.0的版…

记录k8s以docker方式安装Kuboard v3 过程

原本是想通过在k8s集群中安装kuboad v3的方式安装kuboard,无奈在安装过程中遇到了太多的问题,最后选择了直接采用docker安装的方式,后续有时间会补上直接采用k8s安装kuboard v3的教程。 1.kuboard安装文档地址: 安装 Kuboard v3 …

【Jenkins】持续集成与交付 (一):深入理解什么是持续集成?

🟣【Jenkins】持续集成与交付 (一):深入理解什么是持续集成? 1、软件开发生命周期与持续集成2、 持续集成的流程3、持续集成的好处4、Jenkins的应用实践5、结语💖The Begin💖点点关注,收藏不迷路💖 1、软件开发生命周期与持续集成 软件开发生命周期(SDLC)是指软…

windows11安装nginx

1.解压nginx安装包到没有中文的目录 2.双击运行nginx.exe 3.任务管理器查看是否有nginx进程 4.任务管理器->性能->资源监视器 5.网络->侦听端口,查看nginx侦听的端口,这里是90端口

MySQL怎么看死锁记录

这个结果分成三部分: (1) TRANSACTION,是第一个事务的信息; (2) TRANSACTION,是第二个事务的信息; (3)WE ROLL BACK TRANSACTION (1),是最终的处理结果,表示回滚了第一个事务。 第一个事务的信…