最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C語(yǔ)言大小端模式、判斷大小端、大小端轉(zhuǎn)換方法詳解

 更新時(shí)間:2024年10月23日 09:42:26   作者:微塵8  
這篇文章主要介紹了C語(yǔ)言大小端模式、判斷大小端、大小端轉(zhuǎn)換的相關(guān)資料,大端和小端是數(shù)據(jù)在內(nèi)存中的存儲(chǔ)方式,大端模式下高字節(jié)存于低地址,小端模式則相反,大小端問(wèn)題由數(shù)據(jù)類型多字節(jié)存儲(chǔ)引起,不同選擇形成不同存儲(chǔ)模式,需要的朋友可以參考下

1. 什么是大端和小端

對(duì)于一個(gè)存儲(chǔ)空間大于 1 個(gè)字節(jié)的數(shù)據(jù),在內(nèi)存中有兩種存儲(chǔ)模式,

大端模式 (big-endian):數(shù)據(jù)的高字節(jié)在內(nèi)存的低地址存放,數(shù)據(jù)的低字節(jié)在內(nèi)存的高地址存放

小端模式 (little-endian):數(shù)據(jù)的高字節(jié)在內(nèi)存的高地址存放,數(shù)據(jù)的低字節(jié)在內(nèi)存的低地址存放

簡(jiǎn)單記憶:

大端模式:大高低

小端模式:小低低

比如,比如數(shù)字:0x12345678,大小端存儲(chǔ)模式如下:

2.為什么會(huì)存在大小端的問(wèn)題

        在 C 語(yǔ)言中,有占 1 個(gè)字節(jié)內(nèi)存空間的 char 類型,占 2 個(gè)字節(jié)內(nèi)存空間的 short int 類型,以及占 4 個(gè)字節(jié)內(nèi)存空間的 int,double 類型和占 8 個(gè)字節(jié)內(nèi)存空間的 double 類型等等,那么對(duì)于大于 1 個(gè)字節(jié)空間的數(shù)據(jù)類型的數(shù)據(jù)在內(nèi)存中存儲(chǔ)時(shí),就必然產(chǎn)生一個(gè)數(shù)據(jù)在內(nèi)存中應(yīng)該將其低字節(jié)數(shù)據(jù)安排在內(nèi)存的低地址還是高地址呢?,對(duì)這個(gè)問(wèn)題做的不同選擇,就形成了大小端問(wèn)題。

3. 判斷主機(jī)字節(jié)序 (主機(jī)大小端)

3.1 使用聯(lián)合體 (union)

        聯(lián)合體的每一個(gè)成員共用一個(gè)內(nèi)存地址,修改其中一個(gè)成員的數(shù)據(jù),可能會(huì)影響其它成員的數(shù)據(jù)的值。比如以下聯(lián)合體,成本變量 i 和 c 的內(nèi)存地址是相同的,它的內(nèi)存分布示意圖為

	union {
		int i;
		char c;
	}un;	// 匿名聯(lián)合體

#include <stdio.h>

int is_little_endian() {
	union {
		int i;
		char c;
	}un;	// 匿名聯(lián)合體
	un.i = 1;	

	return un.c;	// 小端:返回 1,說(shuō)明數(shù)據(jù)的低字節(jié)在內(nèi)存的低地址存放
					// 大端:返回 0,說(shuō)明數(shù)據(jù)的低字節(jié)在內(nèi)存的高地址存放
}

int main() {
	if (is_little_endian())
		printf("little-endian\n");
	else
		printf("big-endian\n");

	return 0;
}

3.2 使用指針

#include <stdio.h>

int is_little_endian() {
	int i = 1;

	// 等同于 char* p = (char*)&i; return *p;
	return *(char*)&i;	// 小端:返回 1,說(shuō)明數(shù)據(jù)的低字節(jié)在內(nèi)存的低地址存放
						// 大端:返回 0,說(shuō)明數(shù)據(jù)的低字節(jié)在內(nèi)存的高地址存放
}

int main() {
	if (is_little_endian())
		printf("little-endian\n");
	else
		printf("big-endian\n");

	return 0;
}

3.3 強(qiáng)制轉(zhuǎn)為 char 類型法

#include <stdio.h>

int is_little_endian() {
	int i = 1;

	// (char)i : 強(qiáng)轉(zhuǎn)為 char 類型,實(shí)際就是取 i 在內(nèi)存中第一個(gè)字節(jié)的數(shù)據(jù)
	return (char)i;	// 小端:返回 1,說(shuō)明數(shù)據(jù)的低字節(jié)在內(nèi)存的低地址存放
					// 大端:返回 0,說(shuō)明數(shù)據(jù)的低字節(jié)在內(nèi)存的高地址存放
}

int main() {
	if (is_little_endian())
		printf("little-endian\n");
	else
		printf("big-endian\n");

	return 0;
}

4. 大小端轉(zhuǎn)換

1. 編寫大小端轉(zhuǎn)化函數(shù),并打印本機(jī)字節(jié)序下的數(shù)字:0x11223344,分別在小端模式和大端模式下是什么數(shù)據(jù)。

#include <stdio.h>

int is_little_endian();
int to_opposite_endian(int data);
int to_big_endian(int data);
int to_little_endian(int data);

int main() {
	int i = 0x11223344;
	printf("little_endian:	%x\n", to_little_endian(i));
	printf("big_endian:	%x\n", to_big_endian(i));

	return 0;
}

int is_little_endian() {
	int i = 1;

	return (char)i;	// 小端:返回 1,大端:返回 0
}

// 大小端轉(zhuǎn)換
int to_opposite_endian(int data) {
	int size = sizeof(data);
	int des = 0;		// 目標(biāo)數(shù)據(jù)
	int mask = 0xff;	// 掩碼
	int temp;

	for (int i = 0; i < size; i++) {
		des = des << 8;			// 左移8位
		temp = data & mask;		// 取值
		temp = temp >> i * 8;	// 移到低8位
		des |= temp;
		mask = mask << 8;		// 掩碼左移8位,為下一次取數(shù)據(jù)用
	}

	return des;
}

int to_big_endian(int data) {
	if (!is_little_endian())	// 大端
		return data;

	return to_opposite_endian(data);
}

int to_little_endian(int data) {
	if (is_little_endian())	// 小端
		return data;

	return to_opposite_endian(data);
}

2. 在網(wǎng)絡(luò)編程中,可以使用 htonl, htons, ntohl, ntohs 等函數(shù)

  • htonl(uint32_t hostlong) // host to network long,32位無(wú)符號(hào)整型的主機(jī)字節(jié)序轉(zhuǎn)成網(wǎng)絡(luò)字節(jié)序
  • htons(uint16_t hostshort) // host to network short,16位無(wú)符號(hào)短整型的主機(jī)字節(jié)序轉(zhuǎn)成網(wǎng)絡(luò)字節(jié)序
  • ntohl(uint32_t netlong) // network to host long,32位無(wú)符號(hào)整型的網(wǎng)絡(luò)字節(jié)序轉(zhuǎn)成主機(jī)字節(jié)順序的
  • ntohs(uint16_t netshort) //16位無(wú)符號(hào)短整型的網(wǎng)絡(luò)字節(jié)序轉(zhuǎn)成主機(jī)字節(jié)序

網(wǎng)絡(luò)字節(jié)序:大端模式(big-endian),即數(shù)據(jù)的高字節(jié)在內(nèi)存的高地址存放,數(shù)據(jù)的低字節(jié)在內(nèi)存的低地址存放。

附:大小端轉(zhuǎn)換函數(shù)

直接通過(guò)對(duì)地址的操作來(lái)實(shí)現(xiàn) 傳入的變量為32位的變量
中間變量ptr是傳入變量的地址

void swap16(void * p)
{
   uint16_t *ptr=p;
   uint16_t x = *ptr;
   x = (x << 8) | (x >> 8);

   *ptr=x;
}

void swap32(void * p)
{
   uint32_t *ptr=p;
   uint32_t x = *ptr;
   x = (x << 16) | (x >> 16);
   x = ((x & 0x00FF00FF) << 8) | ((x >> 8) & 0x00FF00FF);

   *ptr=x;
}

void swap64(void * p)
{
   uint64_t *ptr=p;
   uint64_t x = *ptr;
   x = (x << 32) | (x >> 32);
   x = ((x & 0x0000FFFF0000FFFF) << 16) | ((x >> 16) & 0x0000FFFF0000FFFF);
   x = ((x & 0x00FF00FF00FF00FF) << 8) | ((x >> 8) & 0x00FF00FF00FF00FF);

   *ptr=x;
}

總結(jié)

到此這篇關(guān)于C語(yǔ)言大小端模式、判斷大小端、大小端轉(zhuǎn)換的文章就介紹到這了,更多相關(guān)C語(yǔ)言判斷大小端、大小端轉(zhuǎn)換內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語(yǔ)言實(shí)現(xiàn)銷售管理系統(tǒng)

    C語(yǔ)言實(shí)現(xiàn)銷售管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)銷售管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • 利用QT實(shí)現(xiàn)UDP聊天小程序

    利用QT實(shí)現(xiàn)UDP聊天小程序

    這篇文章主要為大家詳細(xì)介紹了潤(rùn)滑利用QT的UDP技術(shù),實(shí)現(xiàn)兩個(gè)QT程序之間的聊天程序。文中的示例代碼講解詳細(xì),感興趣的小伙伴可以學(xué)習(xí)一下
    2022-11-11
  • 一篇文章徹底弄懂C++虛函數(shù)的實(shí)現(xiàn)機(jī)制

    一篇文章徹底弄懂C++虛函數(shù)的實(shí)現(xiàn)機(jī)制

    C++中的虛函數(shù)的作用主要是實(shí)現(xiàn)了多態(tài)的機(jī)制,基類定義虛函數(shù),子類可以重寫該函數(shù),在派生類中對(duì)基類定義的虛函數(shù)進(jìn)行重寫時(shí),需要在派生類中聲明該方法為虛方法,這篇文章主要給大家介紹了關(guān)于如何通過(guò)一篇文章徹底弄懂C++虛函數(shù)的實(shí)現(xiàn)機(jī)制,需要的朋友可以參考下
    2021-06-06
  • c語(yǔ)言++放在前面和后面的區(qū)別分析

    c語(yǔ)言++放在前面和后面的區(qū)別分析

    在C語(yǔ)言中,前綴自增(++i)和后綴自增(i++)操作符并不是同一個(gè)操作符,前綴自增操作符的優(yōu)先級(jí)高于后綴自增,同時(shí)得到的結(jié)果并不完全一致,因此需要區(qū)分
    2015-11-11
  • 利用C語(yǔ)言來(lái)求最大連續(xù)子序列乘積的方法

    利用C語(yǔ)言來(lái)求最大連續(xù)子序列乘積的方法

    這篇文章主要介紹了利用C語(yǔ)言來(lái)求最大連續(xù)子序列乘積的方法,基本的思路以外文中還附有相關(guān)ACM題目,需要的朋友可以參考下
    2015-08-08
  • C++?通過(guò)pqxxlib庫(kù)鏈接?PostgreSql數(shù)據(jù)庫(kù)的詳細(xì)過(guò)程

    C++?通過(guò)pqxxlib庫(kù)鏈接?PostgreSql數(shù)據(jù)庫(kù)的詳細(xì)過(guò)程

    這篇文章主要介紹了C++?通過(guò)pqxxlib庫(kù)鏈接?PostgreSql數(shù)據(jù)庫(kù),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-04-04
  • C++調(diào)用C#的DLL實(shí)現(xiàn)方法

    C++調(diào)用C#的DLL實(shí)現(xiàn)方法

    這篇文章主要介紹了C++調(diào)用C#的DLL實(shí)現(xiàn)方法,很有實(shí)用價(jià)值,需要的朋友可以參考下
    2014-07-07
  • C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之?dāng)U展字符詳解

    C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之?dāng)U展字符詳解

    掌握C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)的關(guān)鍵在于理解其核心概念,擴(kuò)展字符作為其中的重要一環(huán),對(duì)于編程人員來(lái)說(shuō)至關(guān)重要,本指南將為您深入剖析擴(kuò)展字符的相關(guān)知識(shí),帶您輕松掌握C語(yǔ)言數(shù)據(jù)結(jié)構(gòu),讓我們一起探索這個(gè)令人著迷的領(lǐng)域吧!
    2024-03-03
  • 淺析C/C++中的可變參數(shù)與默認(rèn)參數(shù)

    淺析C/C++中的可變參數(shù)與默認(rèn)參數(shù)

    C支持可變參數(shù)的函數(shù),這里的意思是C支持函數(shù)帶有可變數(shù)量的參數(shù),最常見的例子就是我們十分熟悉的printf()系列函數(shù)。我們還知道在函數(shù)調(diào)用時(shí)參數(shù)是自右向左壓棧的
    2013-09-09
  • C語(yǔ)言由淺入深了解變量的應(yīng)用

    C語(yǔ)言由淺入深了解變量的應(yīng)用

    這篇文章主要介紹了C語(yǔ)言的變量,變量是C語(yǔ)言語(yǔ)法和語(yǔ)義中一個(gè)很重要的知識(shí)點(diǎn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05

最新評(píng)論

镇原县| 临颍县| 盐亭县| 炉霍县| 山东| 荔波县| 平昌县| 嘉祥县| 乌拉特中旗| 卫辉市| 邯郸市| 双牌县| 奈曼旗| 宾阳县| 鄂尔多斯市| 阳原县| 天全县| 探索| 潜山县| 宕昌县| 双流县| 滦南县| 三台县| 色达县| 石棉县| 武威市| 岫岩| 乌鲁木齐县| 灌云县| 东平县| 陵川县| 班戈县| 织金县| 县级市| 巴南区| 孝感市| 阜康市| 吴忠市| 龙川县| 察哈| 淳化县|