当前位置:首页 » 编程语言 » c语言判断系统大小端
扩展阅读
webinf下怎么引入js 2023-08-31 21:54:13
堡垒机怎么打开web 2023-08-31 21:54:11

c语言判断系统大小端

发布时间: 2022-05-23 21:12:41

1. C语言程序判断电脑的CPU大小端怎么解决

给段代码供参考

intis_little_endian()
{
union
{
charc;
inti;
}u;
u.i=1;
returnu.c==1;
}

2. C语言测试大小端的问题

大端模式,是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;

小端模式,是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低,和我们的逻辑方法一致。

测试程序:

#include<stdio.h>

intmain(void)
{
inta=0x12345678;
unsignedchar*p=(unsignedchar*)&a;

if(0x78==*p)
{
printf("littleend ");
}
else
{
printf("bigend ");
}

return0;
}

3. C语言题目 这题和大小端有关吗

会的,你可以调试的时候打开内存监视看一下这个地址,会发现是小端对齐的,存储为3412cdab。取得首地址的内容为34.而大端对其的话则为abcd1234,所以急首地址的内容为ab。

4. C语言判断处理器大小端对齐原理

大端模式,是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中
小端模式,是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中
上面c是一个共用体,给共用体中的a赋值为1.然后读取b是否为1,当b为1是说明是小端模式,b为0则说明是大端模式。

注意共用体是一个int和一个char,所以才能判断。

5. 大端模式和小端模式

具体如下:


1、大端模式:

大端模式,是指数据的高位,保存在内存的低地址中,而数据的低位,保存在内存的高地址中,这样的存储模式类似于把数据当作字符串顺序处理。

地址由小向大增加,而数据从高位往低位放;小端模式,是指数据的高位保存在内存的高地址中,而数据的低位保存在内存的低地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低,和我们的逻辑方法一致。

在大端模式下,前16位应该这样读: e6 84 6c 4e ( 假设int占4个字节)。

记忆方法: 地址的增长顺序与值的增长顺序相反。

2、小端模式例子:

0000430: e684 6c4e 0100 1800 53ef 0100 0100 0000。

0000440: b484 6c4e 004e ed00 0000 0000 0100 0000。

在小端模式下,前16位应该这样读: 4e 6c 84 e6( 假设int占4个字节)。

记忆方法: 地址的增长顺序与值的增长顺序相同。

大小端模式:

为什么会有大小端模式之分呢?这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为 8bit。但是在C语言中除了8bit的char之外,还有16bit的short型,32bit的long型(要看具体的编译器),另外,对于位数大于 8位的处理器。

例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如何将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式。例如一个16bit的short型x,在内存中的地址为0x0010,x的值为0x1122,那么0x11为高字节,0x22为低字节。

对于 大端模式,就将0x11放在低地址中,即0x0010中,0x22放在高地址中,即0x0011中。小端模式,刚好相反。我们常用的X86结构是小端模式,而KEIL C51则为大端模式。很多的ARM,DSP都为小端模式。有些ARM处理器还可以由硬件来选择是大端模式还是小端模式。

6. C语言程序怎样判断计算机的CPU大小端

写一个C函数,若处理器是Big_endian的,则返回false;若是Little_endian的,则返回true。
boolIsLitte_Endian()
{
union w{
int a;
char b;
}c;
c.a=1;
return (c.b==1);

}

7. 计算机中的大小端模式及C语言中如何鉴别他们

写一个C函数,若处理器是Big_endian的,则返回false;若是Little_endian的,则返回true。boolIsLitte_Endian() { union w{ int a; char b; }c; c.a=1; return (c.b==1); }

8. 大小端模式的判断处理器

通过下列的程序可以确认在某个硬件平台上的某个操作系统是大端还是小端:
VB6: '注意这个CopyMemory的声明与一般的不一样,'一般的都是(pDstAsAny,pSrcAsAny,ByValByteLenAsLong)'为了能够逐字节访问u,所以前面两个参数改成了按值传递,配合VarPtr函数获取变量地址_RtlMoveMemory(ByValpDstAsLong,ByValpSrcAsLong,ByValByteLenAsLong)PrivateSubForm_Load()'VB的Integer占用2个字节!Long才是4个字节'32位应用程序的指针是4个字节sLong'储存u从低地址到高地址的4个字节=367328153'十六进制数:15E4FB99uptr=VarPtr(u)'VarPtr函数是内置函数,但是msdn不说,作用是获取变量的地址aptr=VarPtr(a)bptr=VarPtr(b)cptr=VarPtr(c)dptr=VarPtr(d)CopyMemoryaptr,uptr+0,1'将u逐字节按顺序写入a,b,c,dCopyMemorybptr,uptr+1,1CopyMemorycptr,uptr+2,1CopyMemorydptr,uptr+3,1'Windows系统,英特尔处理器:最后输出的是99FBE415MsgBoxHex(a)&&Hex(b)&&Hex(c)&&Hex(d)EndSub在英特尔处理器,Windows10操作系统上,对话框显示的结果是99 FB E4 15,与直接求出来的16进制值15 E4 FB 99正好相反,所以是小端的。
C++语言(VS2013下,控制台项目): #include<iostream>usingnamespacestd;typedefunsignedcharbyte;//转换char(视为整数类型)为16进制字符串voidChtoHex(byteVal,char*dest){//辗转相除法,倒序看得到结果bytetmp=Val%16;if(tmp>=0&&tmp<=9){dest[1]='0'+tmp;}elseif(tmp>=10&&tmp<=15){dest[1]='A'+tmp-10;}tmp=(Val/16)%16;if(tmp>=0&&tmp<=9){dest[0]='0'+tmp;}elseif(tmp>=10&&tmp<=15){dest[0]='A'+tmp-10;}//设置''dest[2]='';}//主函数intmain(){intu=367328153;//原始数据,8位16进制为15E4FB99bytea,b,c,d;//u从低地址到高地址的四个字节//a~d对应的16进制字符串,预留3个字符charSa[3],Sb[3],Sc[3],Sd[3];byte*k=(byte*)&u;a=k[0];b=k[1];c=k[2];d=k[3];//转成16进制字符串ChtoHex(a,Sa);ChtoHex(b,Sb);ChtoHex(c,Sc);ChtoHex(d,Sd);cout<<Sa<<<<Sb<<<<Sc<<<<Sd<<endl;system(pause);return0;}在英特尔处理器,Windows10操作系统上,控制台显示的结果是99 FB E4 15,与直接求出来的16进制值15 E4 FB 99正好相反,所以也证明是小端的。
C语言(VC++6.0,控制台工程): #include<stdio.h>typedefunsignedcharbyte;//转换char(视为整数类型)为16进制字符串voidChtoHex(byteVal,char*dest){//辗转相除法,倒序看得到结果bytetmp=Val%16;if(tmp>=0&&tmp<=9){dest[1]='0'+tmp;}elseif(tmp>=10&&tmp<=15){dest[1]='A'+tmp-10;}tmp=(Val/16)%16;if(tmp>=0&&tmp<=9){dest[0]='0'+tmp;}elseif(tmp>=10&&tmp<=15){dest[0]='A'+tmp-10;}//设置dest[2]='';}//主函数voidmain(){intu=367328153;//原始数据,8位16进制为15E4FB99bytea,b,c,d;//u从低地址到高地址的四个字节//a~d对应的16进制字符串,预留3个字符charSa[3],Sb[3],Sc[3],Sd[3];byte*k=(byte*)&u;a=k[0];b=k[1];c=k[2];d=k[3];//转成16进制字符串ChtoHex(a,Sa);ChtoHex(b,Sb);ChtoHex(c,Sc);ChtoHex(d,Sd);printf(%s%s%s%s ,Sa,Sb,Sc,Sd);scanf_s(%d,&a);}在英特尔处理器,Windows10操作系统上,结果跟上面是一样的,输出的16进制数是反序的,证明是小端系统。
C#(VS2013下,控制台项目): usingSystem;namespaceConsoleApplication1{classProgram{staticvoidMain(string[]args){intu=367328153;//原始数据,8位16进制为15E4FB99byte[]bytes;//u从低地址到高地址的四个字节//获取bytes=System.BitConverter.GetBytes(u);Console.WriteLine(bytes[0].ToString(X)++bytes[1].ToString(X)++bytes[2].ToString(X)++bytes[3].ToString(X));Console.ReadLine();}}}在英特尔处理器,Windows10操作系统上,结果跟上面还还是一样的,输出的16进制数是反序的,证明是小端系统。
MDK(Keil5,STM32F407)C语言: #includestm32f4xx.hintmain(void){intu=367328153;//原始数据15E4FB99int*k=&u;return0;}编译连接然后下载到开发板上,然后启动调试,通过监视窗口可以看到u的地址,然后在内存窗口可以看到字节序是反序的,所以说明STM32F407是小端的。据某些资料说ARM内核是可以设置大小端的,但是STM32是外设自动进入了小端,似乎是无法调整的。

89C52(Keil5)C语言:
最后来一个大端的例子。手头上没有51的开发板,所以用的是软件仿真。 #include<reg52.h>intmain(){intlongbit=sizeof(long);longu=367328153;//原始数据15E4FB99long*k=&u;return0;}注意看了,C52是8位的处理器,long才是4个字节的,看监视窗口longbit的值就知道了(紫色框)。然后再看内存窗口,就会发现u的存储是跟原始数据给的顺序是一样的,所以C51和C52是大端的!!

9. C语言读写二进制文件读取 大小端,该怎么解

先看下面的代码,然后我在简短的解释一下。

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <string>#define nmemb 7/****************************************************
Date types(Compiler specific) 数据类型(和编译器相关)
*****************************************************/typedef unsigned char uint8; /* Unsigned 8 bit quantity */typedef signed char int8; /* Signed 8 bit quantity */typedef unsigned short uint16; /* Unsigned 16 bit quantity */typedef signed short int16; /* Signed 16 bit quantity */typedef unsigned int uint32; /* Unsigned 32 bit quantity */typedef signed int int32; /* Signed 32 bit quantity */typedef float fp32; /* Single precision */
/* floating point */typedef double fp64; /* Double precision */
/* floating point *///int32#define BigtoLittle32(A) ((( (uint32)(A) & 0xff000000 ) >> 24) |
(( (uint32)(A) & 0x00ff0000 ) >> 8) |
(( (uint32)(A) & 0x0000ff00 ) << 8) |
(( (uint32)(A) & 0x000000ff ) << 24))//int16#define BigtoLittle16(A) (( ((uint16)(A) & 0xff00) >> 8 ) |
(( (uint16)(A) & 0x00ff ) << 8))/************************************************************
* Conversion little endian float data to big endian
* *************************************************************/float ReverseFloat(const float inFloat)
{ float retVal; char *floatToConvert = (char*) & inFloat; char *returnFloat = (char*) & retVal; // swap the bytes into a temporary buffer
returnFloat[0] = floatToConvert[3];
returnFloat[1] = floatToConvert[2];
returnFloat[2] = floatToConvert[1];
returnFloat[3] = floatToConvert[0]; return retVal;
}struct matrix
{ int row; int column;
}s[nmemb];void set_s(int j, int x, int y)
{
s[j].row = x;
s[j].column = y;
}bool is_bigendian()
{ int a = 0x1234; char b = *(char *)&a; //b == the Low address part of a
//printf("%c ", b);
if (b == 0x34) { return false;
} return true;
}int main()
{ if (is_bigendian()) { printf("BigEndian ");
} else { printf("LittleEndian ");
}

FILE *fp;
set_s(0, 1, 50);
set_s(1, 1, 80);
set_s(2, 4, 20);
set_s(3, 50, 1);
set_s(4, 80, 2);
set_s(5, 100, 3);
set_s(6, 100, 4); int ans = sizeof(struct matrix); printf("size: %d ", ans); printf("size: %d ", sizeof(s)); if ((fp = fopen("test", "wb")) == NULL) { printf("EROOR "); return 1;
} for (int j = 0; j < nmemb; ++j) { printf("row: %d column: %d ", s[j].row, s[j].column);
}
fwrite(s, sizeof(struct matrix), nmemb, fp); for (int i = 0; i < nmemb; ++i) { float *m = (float*) malloc(sizeof(float) * s[i].row * s[i].column);
bzero(m, sizeof(float) * s[i].row * s[i].column); for (int j = 0; j < s[i].row; ++j) { for (int k = 0; k < s[i].column; ++k) {
m[k + j*s[i].column] = k;
}
}
fwrite(m, sizeof(float), s[i].row * s[i].column, fp); free(m);
}

fclose(fp); printf("11 "); /*
printf("%d ", sizeof(float));
FILE *fp;
if ((fp = fopen("test", "rb")) == NULL) {
printf("EROOR ");
return 1;
}
fread(s, sizeof(struct matrix), nmemb, fp);
for (int i = 0; i < nmemb; ++i) {
printf("row: %d column: %d ", s[i].row, s[i].column);
}

for (int i = 0; i < nmemb; ++i) {
float *m = (float*) malloc(sizeof(float) * s[i].row * s[i].column);
bzero(m, sizeof(float) * s[i].row * s[i].column);
fread(m, sizeof(float), s[i].row * s[i].column, fp);
for (int j = 0; j < s[i].row; ++j) {
for (int k = 0; k < s[i].column; ++k) {
printf("%lf ", m[k + j*s[i].column]);
}
printf(" ");
}
printf(" ");
free(m);
}
fclose(fp);
*/
return 0;
}

fopen和fclose是很常见的,在这里就不做解释了。我们来看看fwrite和fread,本来以为这个很麻烦,但是用过之后发现这个二进制文件读写才是最简单的。

size_t fwrite(const void * ptr,size_t size,size_t nmemb,FILE * stream);
fwrite()用来将数据写入文件流中。
stream为已打开的文件指针
ptr 指向欲写入的数据地址
写入的字符数以参数size*nmemb来决定。
size表示写入一个nmemb的内存大小。
fwrite()会返回实际写入的nmemb数目。

size_t fread(void * ptr,size_t size,size_t nmemb,FILE * stream);
fread()用来从文件流中读取数据。
stream为已打开的文件指针
ptr 指向欲存放读取进来的数据空间
读取的字符数以参数size*nmemb来决定
size表示读取一个nmemb的内存大小。
fread()会返回实际读取到的nmemb数目,如果此值比参数nmemb 小,则代表可能读到了文件尾或有错误发生,这时必须用feof()或ferror()来决定发生什么情况。
返回实际读取到的nmemb数目。

详情参见上面的代码。

另外就是大小端的问题了。关于大小端的具体解释网上有很多,在此不作解释。参考上面写的代码,我判断了自己机器是大端还是小端,并且实现了int16,int32已经float数据类型的大小端转换,大端转小端,在使用相同的代码一次小端又变成了大端。

PS:float的大小端转化我之前一直以为写的是错的,因为好多数据转化之后输出都是0。后来发现可能是与float类型在内存中的存放有关,我们的程序是对的。

10. C语言中使用union是怎么判断处理器大小端的

union Charge

{
char arr[2];
short num;
};
int main()
{

union Charge charge;
charge.arr[0] = 1;
charge.arr[1] = 2;

if (charge.num == 0x0201)
{
printf("小端\n");

}
else
{
printf("大端\n");

}

return 0;
}