c语⾔struct结构体强制类型转换
1、⽆结构体标签
struct {
int in;
int out;
}GPIO_t;
声明了⼀个⽆名结构体,并创建了⼀个结构体变量GPIO_t(已分配空间),该⽅法只适合创建⼀个结构体变量
typedef struct {
int in;
int out;
}GPIO_t;
/*静态分配内存*/
GPIO_t GPIOA;
/*动态分配内存*/
GPIO_t *GPIOA = (GPIO_t*)malloc(sizeof(GPIO_t));
free(GPIOA);
2、显⽰声明结构体标签
struct _GPIO_t{
int in;
int out;
};
如需声明多个结构体变量:struct _GPIO_t GPIOA,GPIOB;
注:常⽤第⼆种⽅法声明创建结构体,具体⾼级⽤法请看下⾯讲解c语言struct头文件
⼆、强制类型转换
1、普通数据类型强制转换,使⽤强制类型转换符
(type_name) expression
例如:
int sum = 17, count = 5;
double mean;
mean = (double)sum / count;
printf("Value of mean : %f \n",mean);
编译运⾏输出以下结果:
注:这⾥要注意的是强制类型转换运算符的优先级⼤于除法,因此 sum 的值⾸先被转换为 double 型,然后除以 count,得到⼀个类型为 double 的值
2、数据类型强制转化为结构体类型
#include <stdio.h>
int main (void) {
int a[] = {1,2,'a','b'};
typedef struct _GPIO_t{
int in;
int out;
int type;
int value;
}GPIO_t;
GPIO_t *GPIOA = (GPIO_t *) &a;
/*
* 等同于GPIO_t *GPIOA = (GPIO_t *) &a;
* 因为数组的⾸地址为可以表⽰为 a,&a,&a[0]
*/
printf("%d \n",GPIOA->in);
printf("%d \n",GPIOA->out);
printf("%c \n",GPIOA->type);
printf("%c \n",GPIOA->value);
}
编译运⾏如何结果:
注:通过该⽅法可以把某⼀起始地址的数据类型与结构体成员相对应,以后直接通过结构体成员去访问结构体成员之间默认32位对齐,在定义成员时需要特别注意
实⽤举例:
#include <stm32f10x.h>
typedef struct
{
__IO uint32_t CRL;
__IO uint32_t CRH;
__IO uint32_t IDR;
__IO uint32_t ODR;
__IO uint32_t BSRR;
__IO uint32_t BRR;
__IO uint32_t LCKR;
} GPIO_TypeDef;
/*Peripheral base address define*/
#define PERIPH_BASE ((uint32_t)0x40000000) /*!< Peripheral base address in the alias region */
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
#define GPIOA_BASE (APB2PERIPH_BASE + 0x0800)
#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)
/*函数调⽤*/
#include "led.c"
void LED_Init(void)
{
RCC->APB2ENR|=1<<3; // 使能PORTA时钟
GPIOA->CRL&=0XFF0FFFFF;
GPIOA->CRL|=0X00300000;//PA.5 推挽输出
GPIOA->ODR|=1<<5; //PA.5 输出⾼
}
三、给结构体变量赋值
GPIO_t GPIOB = {
.in = 3,
.
out = 4,
.type = 'A',
.value = 'B'
};
printf("%d \n",GPIOB.in);
printf("%d \n",GPIOB.out);
printf("%c \n",pe);
printf("%c \n",GPIOB.value);
注:callback函数使⽤时,直接给成员变量赋值
*举例说明结构体成员数据类型对齐问题
1、成员变量字节已经对齐使⽤
int a[] = {'abcd',4444};
typedef struct _GPIO_t{
char in;
char out;
char type;
char value;
int data;
}GPIO_t;
GPIO_t *GPIOA = (GPIO_t *) &a;
printf("%c \n",GPIOA->in);
printf("%c \n",GPIOA->out);
printf("%c \n",GPIOA->type);
printf("%c \n",GPIOA->value);
printf("%d \n",GPIOA->data);
编译运⾏输出结果:
注:数据存储格式分为⼤⼩端存储,所以结构引⽤输出顺序可能不太对应2、成员变量没有对齐
int a[] = {1234,5678,'abcd',4444};
typedef struct _GPIO_t{
int in;
int out;
char type;
char value;
int data; //会⾃动四字节对齐因此直接指向a[3]
}GPIO_t;
GPIO_t *GPIOA = (GPIO_t *) &a;
printf("%d \n",GPIOA->in);
printf("%d \n",GPIOA->out);
printf("%c \n",GPIOA->type);
printf("%c \n",GPIOA->value);
printf("%d \n",GPIOA->data);
编译运⾏结果:
注:因为⾃动对齐缘故,其中有些数据会⾃动丢掉
3、成员变量不使⽤⾃动给对齐
int a[] = {1234,5678,'abcd',4444};
/*
* ARM系统使⽤ __packed取消字节对齐
*/
#pragma pack(1) //强制设置1字节对齐
typedef struct _GPIO_t{
int in;
int out;
char type;
char value;
int data; //会⾃动四字节对齐因此直接指向a[3]
} GPIO_t;
GPIO_t *GPIOA = (GPIO_t *) &a;
printf("%d \n",GPIOA->in);
printf("%d \n",GPIOA->out);
printf("%c \n",GPIOA->type);
printf("%c \n",GPIOA->value);
printf("%d \n",GPIOA->data);
编译运⾏结果:
注:最后⼀个成员由于对齐错误出现乱码
### 转载,原⽂出处:[原⽂](blog.csdn/blog_xu/article/details/84374473)
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论