c語(yǔ)言struct結(jié)構(gòu)體強(qiáng)制類(lèi)型轉(zhuǎn)換的實(shí)現(xiàn)
一、 關(guān)于struct相關(guān)說(shuō)明
1、無(wú)結(jié)構(gòu)體標(biāo)簽
struct {
int in;
int out;
}GPIO_t;
聲明了一個(gè)無(wú)名結(jié)構(gòu)體,并創(chuàng)建了一個(gè)結(jié)構(gòu)體變量GPIO_t(已分配空間),該方法只適合創(chuàng)建一個(gè)結(jié)構(gòu)體變量
typedef struct {
int in;
int out;
}GPIO_t;
/*靜態(tài)分配內(nèi)存*/
GPIO_t GPIOA;
/*動(dòng)態(tài)分配內(nèi)存*/
GPIO_t *GPIOA = (GPIO_t*)malloc(sizeof(GPIO_t));
free(GPIOA);
使用typedef關(guān)鍵字,可以為結(jié)構(gòu)體GPIO_t創(chuàng)建多個(gè)變量,例如:GPIO_t GPIOA,GPIOB;
2、顯示聲明結(jié)構(gòu)體標(biāo)簽
struct _GPIO_t{
int in;
int out;
};
如需聲明多個(gè)結(jié)構(gòu)體變量:struct _GPIO_t GPIOA,GPIOB;
注:常用第二種方法聲明創(chuàng)建結(jié)構(gòu)體,具體高級(jí)用法請(qǐng)看下面講解
二、強(qiáng)制類(lèi)型轉(zhuǎn)換
1、普通數(shù)據(jù)類(lèi)型強(qiáng)制轉(zhuǎn)換,使用強(qiáng)制類(lèi)型轉(zhuǎn)換符
(type_name) expression
例如:
int sum = 17, count = 5;
double mean;
mean = (double)sum / count;
printf("Value of mean : %f \n",mean);
編譯運(yùn)行輸出以下結(jié)果:

注:這里要注意的是強(qiáng)制類(lèi)型轉(zhuǎn)換運(yùn)算符的優(yōu)先級(jí)大于除法,因此 sum 的值首先被轉(zhuǎn)換為 double 型,然后除以 count,得到一個(gè)類(lèi)型為 double 的值
2、數(shù)據(jù)類(lèi)型強(qiáng)制轉(zhuǎn)化為結(jié)構(gòu)體類(lèi)型
#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;
* 因?yàn)閿?shù)組的首地址為 可以表示為 a,&a,&a[0]
*/
printf("%d \n",GPIOA->in);
printf("%d \n",GPIOA->out);
printf("%c \n",GPIOA->type);
printf("%c \n",GPIOA->value);
}
編譯運(yùn)行如何結(jié)果:

注:通過(guò)該方法可以把某一起始地址的數(shù)據(jù)類(lèi)型與結(jié)構(gòu)體成員相對(duì)應(yīng),以后直接通過(guò)結(jié)構(gòu)體成員去訪問(wèn)
結(jié)構(gòu)體成員之間默認(rèn)32位對(duì)齊,在定義成員時(shí)需要特別注意
實(shí)用舉例:
#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)
/*函數(shù)調(diào)用*/
#include "led.c"
void LED_Init(void)
{
RCC->APB2ENR|=1<<3; // 使能PORTA時(shí)鐘
GPIOA->CRL&=0XFF0FFFFF;
GPIOA->CRL|=0X00300000;//PA.5 推挽輸出
GPIOA->ODR|=1<<5; //PA.5 輸出高
}
三、給結(jié)構(gòu)體變量賦值
GPIO_t GPIOB = {
.in = 3,
.out = 4,
.type = 'A',
.value = 'B'
};
printf("%d \n",GPIOB.in);
printf("%d \n",GPIOB.out);
printf("%c \n",GPIOB.type);
printf("%c \n",GPIOB.value);
注:callback函數(shù)使用時(shí),直接給成員變量賦值
*舉例說(shuō)明結(jié)構(gòu)體成員數(shù)據(jù)類(lèi)型對(duì)齊問(wèn)題
1、成員變量字節(jié)已經(jīng)對(duì)齊使用
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);
編譯運(yùn)行輸出結(jié)果:

注:數(shù)據(jù)存儲(chǔ)格式分為大小端存儲(chǔ),所以結(jié)構(gòu)引用輸出順序可能不太對(duì)應(yīng)
2、成員變量沒(méi)有對(duì)齊
int a[] = {1234,5678,'abcd',4444};
typedef struct _GPIO_t{
int in;
int out;
char type;
char value;
int data; //會(huì)自動(dòng)四字節(jié)對(duì)齊因此直接指向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);
編譯運(yùn)行結(jié)果:

注:因?yàn)樽詣?dòng)對(duì)齊緣故,其中有些數(shù)據(jù)會(huì)自動(dòng)丟掉
3、成員變量不使用自動(dòng)給對(duì)齊
int a[] = {1234,5678,'abcd',4444};
/*
* ARM系統(tǒng)使用 __packed取消字節(jié)對(duì)齊
*/
#pragma pack(1) //強(qiáng)制設(shè)置1字節(jié)對(duì)齊
typedef struct _GPIO_t{
int in;
int out;
char type;
char value;
int data; //會(huì)自動(dòng)四字節(jié)對(duì)齊因此直接指向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);
編譯運(yùn)行結(jié)果:

注:最后一個(gè)成員由于對(duì)齊錯(cuò)誤出現(xiàn)亂碼
到此這篇關(guān)于c語(yǔ)言struct結(jié)構(gòu)體強(qiáng)制類(lèi)型轉(zhuǎn)換的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)c語(yǔ)言struct結(jié)構(gòu)體強(qiáng)制類(lèi)型轉(zhuǎn)換內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- C++引用和強(qiáng)制類(lèi)型轉(zhuǎn)換問(wèn)題小結(jié)
- C++強(qiáng)制類(lèi)型轉(zhuǎn)換詳細(xì)示例代碼
- C語(yǔ)言中的數(shù)據(jù)類(lèi)型強(qiáng)制轉(zhuǎn)換
- c#強(qiáng)制類(lèi)型轉(zhuǎn)換int方式
- C++類(lèi)的自動(dòng)轉(zhuǎn)換和強(qiáng)制類(lèi)型轉(zhuǎn)換的實(shí)現(xiàn)示例
- C語(yǔ)言中強(qiáng)制類(lèi)型轉(zhuǎn)換的常見(jiàn)方法
- C++中的強(qiáng)制類(lèi)型轉(zhuǎn)換操作詳解
相關(guān)文章
C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單學(xué)生管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單學(xué)生管理系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01
C++使用string的大數(shù)取模運(yùn)算(5)
這篇文章主要為大家詳細(xì)介紹了C++使用string的大數(shù)取模運(yùn)算,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-09-09
Vs?Code中C/C++配置launch.json和tasks.json文件詳細(xì)步驟
使用VSCode開(kāi)發(fā)C/C++程序,需要配置tasks.json/launch.json,下面這篇文章主要給大家介紹了關(guān)于Vs?Code中C/C++配置launch.json和tasks.json文件的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下2024-01-01
C語(yǔ)言之整數(shù)與浮點(diǎn)數(shù)運(yùn)算的類(lèi)型轉(zhuǎn)換規(guī)則詳解
這篇文章主要介紹了C語(yǔ)言之整數(shù)與浮點(diǎn)數(shù)運(yùn)算的類(lèi)型轉(zhuǎn)換規(guī)則,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-03-03
C語(yǔ)言數(shù)組實(shí)現(xiàn)掃雷游戲
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言數(shù)組實(shí)現(xiàn)掃雷游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06
C++實(shí)現(xiàn)折半插入排序(BinaryInsertSort)
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)折半插入排序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-04-04

