linux下c语言的大小端

25 篇文章 0 订阅

近来在ubuntu下开发c,网络编程方面的,遇到网络字节序,和本地字节序 大小端的问题。

1、判断大小端的简单方法:

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

int main(void)
{
	unsigned int i = 1;
	if(*((char*)&i) == 0)
	{
		printf("this is big endian. \n");
	}
	else if(*((char*)&i) == 1)
	{
		printf(" this is little endian. \n");
	} 
	else
	{
		printf("sorry, i do not know . \n");
	}
	return 0;
}


结果是:(如图)

当然,windows和ubuntu系统都是little endian 系统。


分析:

整形变量 i 在内存中占4个字节,所以有 32位;下图中显示的是:每个字节是 8 位二进制的数字,用 2 位十六进制表示 。所以 0x 0000 0001,表示 32 位 二进制数字, 是变量 i 在内存中的表示。(16进制的8位表示的是内存中的4个字节)

而指针指向最低位,所以上面的程序可以检测大小端的问题。

并且如果是大端的话,当前地址加3位 (+ 3)便得到了最末位的数值,末位为 ‘01’。(下图中红笔的指向)


所以有下面的代码并且相应的结果是:

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

int main(void)
{
	unsigned long i = 1;
	if(*((char*)&i) == 1)
	{
		printf("this is little endian.\n");
		printf("i   == %p . %d, \n", ((char*)&i)+0, *(((char*)(&i))+0) );//
		printf("i+1 == %p . %d, \n" , ((char*)&i)+1, *(((char*)(&i))+1));//高一个字节
		printf("i+2 == %p . %d, \n" , ((char*)&i)+2, *(((char*)(&i))+2));//高二个字节
		printf("i+3 == %p . %d, \n" , ((char*)&i)+3, *(((char*)(&i))+3));//高三个字节
		
		printf("i-1 == %p . %d,\n", *(((char*)(&i))-1) , ((char*)&i)-1);//低一个字节
		printf("i+4 == %p . %d,\n", *(((char*)(&i))+4) , ((char*)&i)+4);//高四个字节
	}
	else if(*((char*)&i) == 0)
	{
		printf("this is big endian. \n");
	}
	else
	{
		printf("i do not know. \n");
	}
	return 0;
}


结果:

即:在 i 的指针,所指向的空间存储的是:0000 0001 ,高一个字节的位置存储的是 0000 0000,高两个字节,和高三个字节也是 0000 0000。

但是 高四个字节和低一个字节的位置存储的是 不定的数值。 

2、htonl()和ntohl()方法的学习

#include <stdlib.h>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>

int main(void)
{
	unsigned long i = 1;
	if(*((char*)&i) == 1)
	{
		printf("this is little endian.\n");
	}
	else if(*((char*)&i) == 0)
	{
		printf("this is big endian. \n");
	}
	else
	{
		printf("i do not know. \n");
	}

	i = ntohl(i);
	printf("%lu \n", i);
	printf("%#x \n", i);
	printf("%#o \n", i);

	i = ntohl(i);
	printf("%lu \n", i);
	printf("%#x \n", i);
	printf("%#o \n", i);

	return 0;
}



结果为:


结果分析:
(1)、是把内存中的二进制:  00000000 00000000 00000000 00000001,
按照字节反转过来为: 00000001 00000000 00000000 00000000 ,

自然数2的24次方结果为16777216

转换成十进制为: 16777216;

转换成十六进制为:0x0100 0000;
转换成八进制为:o 010 0000 0000。(红色的0x和o代表是十六进制和八进制)
(2)、从两个方法来看,htonl和ntohl都是实现了反转;并且经过验证,上面的ntohl()方法,和htonl()方法,都可以互换;
所以两个方法内部的实现应该是一样。


                
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值