首先,什么是大小端存储方式? 大端(存储)模式,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址 中; 小端(存储)模式,是指数据的低位保存在内存的低地址中,而数据的高位,,保存在内存的高地 址中。 改变其中一个数据的值,其他数据的值可能也会随之变化 int is_byteorder(int* p) { union un { //定义一个联合体类型 int i; char c; }u; u.i = 1;//修改i的值,c的值也会随之发生变化 return u.c; } int main() { int n = 2; int ret = ("大端\n"); } return 0; } 如果将 i 改为1,如果是小端存储,就会将01存储到 c 中,就会返回1
上一个专题我们详细的分享了c语言里面的结构体用法,读者在看这些用法的时候,可以一边看一边试验,掌握了这些基本用法就完全够用了,当然在以后的工作中,如果有遇到了更高级的用法,我们可以再来总结学习归纳。 三、大小端模式: 1、什么是叫大小端模式? a、什么叫大端模式(big-endian)? 在这种格式中,字数据的高字节存储在低地址中,而字数据的低字节则存放在高地址中。 (2)移位: 结论:移位的方式也不能测试机器大小端。 理论分析:原因和&运算符不能测试一样,因为C语言对运算符的级别是高于二进制层次的。 这就是通信中的大小端问题。 (3)一般来说是:先发低字节叫小端;先发高字节就叫大端。在实际操作中,在通信协议里面会去定义大小端,明确告诉你先发的是低字节还是高字节。 (4)在通信协议中,大小端是非常重要的,大家使用别人定义的通信协议还是自己要去定义通信协议,一定都要注意标明通信协议中大小端的问题。
领8888元新春采购礼包,抢爆款2核2G云服务器95元/年起,个人开发者加享折上折
如何判断一台计算机的CPU是大端还是小字端对齐呢? 那么首先得了解何为大端,何为小端,明确一下概念。 小端格式:与大端存储格式相反,在小端存储格式中,低地址中存放的是字数据的低字节,高地址存放的是字数据的高字节。 那么如何使用C语言程序判断CPU是大端还是小端对齐呢? 有几个方法: 方法一:直接使用看变量的内存值,这里需要使用一些调试技巧。 运行结果为: 0012FF7C 34 12 方法二:使用C中的共用体: 请写一个C函数,若处理器是Big_endian c.a=1; return (c.b==1); } 方法三:强制类型转换,和共用体的做法差不多。
MDK(Keil5,STM32F407)C语言: #include "stm32f4xx.h" int main(void) { int u = 367328153; // 原始数据 据某些资料说ARM内核是可以设置大小端的,但是STM32是外设自动进入了小端,似乎是无法调整的。 89C52(Keil5)C语言: 来一个大端的例子。手头上没有51的开发板,所以用的是软件仿真。 然后再看内存窗口,就会发现u的存储是跟原始数据给的顺序是一样的,所以C51和C52是大端的!! ? 目前Intel的80x86系列芯片是唯一还在坚持使用小端的芯片,ARM芯片默认采用小端,但可以切换为大端;而MIPS等芯片要么采用全部大端的方式储存,要么提供选项支持大端——可以在大小端之间切换。 另外,对于大小端的处理也和编译器的实现有关,在C语言中,默认是小端(但在一些对于单片机的实现中却是基于大端,比如Keil 51C),Java是平台无关的,默认是大端。
这里涉及大小端的问题,我记为 “小高高,小弟弟(低低)”,就是: “小端模式,是指数据的高位保存在内存的高地址中,数据的低位保存在内存的低地址中” 这是记小端模式的,有点黄,不过好记! : #include<stdio.h> struct mybitfields { unsigned short a:4; unsigned short b:5; unsigned short c: ,大小和short的一样大! 执行完下面的三条语句之后 test.a=2; test.b=3; test.c=0; 内存分布如下: ? 这里x86是小端模式,所以数据分布式上面的,而不是我们理所当然的0010 00011 0000000!
实际工程中,这个结构体可以是一个非常大的结构体对象,比如nginx中的ngx_event_t 2、存在一个较小的结构体b,demo中命名为my_str_t。 实际工程中,这个结构体可以是一个较小的结构体对象。比如nginx中的ngx_rbtree_node_t 3、为结构体a分配空间,维护结构体a中的成员b的地址。 如果将fullname_ptr转换为(int *)类型,这样再减4的时候,会在0x8fde00c的基础上,减掉16个字节。 fullname成员的地址,可以被保存在公用数据结构中,比如hash或tree中作为节点。 具体参见: src/event/ngx_event_timer.c 中的如下代码 if ((ngx_msec_int_t) (node->key - ngx_current_msec)
例23:C语言实现从小到大对10个数进行排序,要求使用冒泡排序实现。 解题思路:排序的规律有两种:一种是“升序”,从小到大;另一种是“降序”,从大到小。 源代码演示: #include<stdio.h>//头文件 int main()//主函数 { int i,j,t;//定义整型变量 int array[10];//定义数组大小 printf C语言冒泡排序比较大小 更多案例可以go公众号:C语言入门到精通
解题思路:这个问题的逻辑很简单,主要就是把比较大小的逻辑抽取出来即可,比较大小具体可以参考之前的文章:C语言 | 由小到大输出两个数。 int max_Fun(int x,int y)//自定义比大小函数 { int temp;//定义中间变量 temp=x>y? /调用max_Fun printf("大的数是:%d",max);//输出结果 return 0;//主函数返回值为0 } int max_Fun(int x,int y)//自定义比大小函数 注意:键盘输入两个数时,中间的逗号应该时英文状态下的,因为代码中的逗号是英文的,scanf函数键盘输入的要和代码保存一致,如果是中文的会输出以下结果。 留个问题,读者请思考如果比较的是小数的大小上面代码应该怎么改? C语言 | 函数实现比较大小 更多案例可以go公众号:C语言入门到精通
笔者在日常项目中经常需要使用C语言求一个文件的大小,特整理了一些常用的方法,通过测试代码的形式展示出来,话不多说,直接上代码: #include <stdio.h> #include <stdlib.h (TEST_FILE); printf("file_size=%d\n\n\n", file_size); return 0; } ---- 测试记录如下: 被测试文件,在windows下查看大小为 好了,本次使用C语言获取文件大小的方法就介绍到这里,如果你有更加方便、快捷、高效的方法,也可以在评论席告知,感激不尽。
直入主题,要判断一个结构体所占的空间大小,大体来说分三步走: 1.先确定实际对齐单位,其由以下三个因素决定 1> CPU周期 WIN vs qt 默认8字节对齐 Linux (取两者中小的那个) 3.结构体的整体大小必须为实际对齐单位的整数倍。 上面三步即是万能公式,下面看实际例子(linux 64系统下): 1. nums中,没有手动设置对齐单位,linux64系统的默认对齐单位是8字节,结构体nums的最大成员double d占8个字节,故实际对齐字节是二者最小 char a放在结构体的起始地址; short b占2个字节,2小于实际对齐字节8,故b的起始地址相对于a的起始地址的偏移量须为2的整数倍个字节; int c占4个字节,4小于实际对齐字节8,故c 起始地址相对于 +8(d)+13(arr)=29;但29并不满足上面三步走的最后一步:“整个结构体的大小必须是实际对齐单位的整数倍”,所以29+5(浪费空间)=32,所以最后nums的空间情况是1(a)+1(浪费空间)
问题 C 语言中如何确定数组的元素个数? 回答 int a[17]; size_t n = sizeof(a) / sizeof(int); 但上面的写法还有点不足。
很多同学在学习C语言,只是局限于课本知识的学习及应用,课本上的练习题做了不少,可一旦遇到实际应用中的问题,就感到无从下手。 以下就简单的就printf函数进行分析。 C程序的输出结果是在标准的输出设备上,通常情况下,在Win环境下,其输出在一个字符窗口上,现在试问,如何得到该字符输出窗口的大小,也即该窗口容纳多少字符,?行 * ?列。
例62:有一个已经排好序的数组,要求C语言实现输入一个数后,按原来排序的规律将它插入数组中。 输入要插入的数:\n");//提示语句 scanf("%d",&num);//键盘录入要插入的数 end=a[9];//将最后一个数赋值给end if(num>end)//先和最后一个数比大小 j++) { t2=a[j]; a[j]=t1; t1=t2; } //把要插入的数放到数组中 以上,如果你看了觉得对你有所帮助,就给小林点个赞,分享给身边的人叭,这样小林也有更新下去的动力,跪谢各位父老乡亲啦~ C语言 | 将一个数按大小顺序插入数组中 更多案例可以go公众号:C语言入门到精通
网络二进制数据转换: 总所周知,数据在tcp网络传输协议中传输的字节序是大端模式的,换句话说如果你要传输一个int32型的整数,那么假设其二进制小端模式表示为11111111111111110000000000000000 那么其大端模式表示为00000000000000001111111111111111,利用c语言的htonl函数会将数据字节序转换成大端模式,在网络上面传输,接收端想解出原始数据只需要认为发送来的数据是大端模式 ,按照大端模式表示的数据解析便可 举个例子: 在C语言端发送一个int32_t数据过程如下: 发送端(c语言) char buf[100]; int32_t x = 100; (( int*)buf)[0] = htonl(x); send(clientfd, buf, 100, 0); 接收端(golang) var num int32 buffer := make
尤其是嵌入式编程以及网络编程中好多地方都有这样的要求,这时候怎么做呢? 这个时候如果是在linux下,就需要用到GNU C 的__attribute__ 机制。 比如: struct A { int i; char c; } __attribute__((packed)); 那么这个结构体的长度就是sizeof(int)+sizeof(c)的大小
目录 一、先写好框架 二、然后定义我们需要的变量 三、这里就要写函数的部分 四、函数部分写完了,但是还一个地方,要值得注意 一、常规方法比较大小 二、指针操作比较大小 今天我们要写的是用调用函数的方法来 比较两个数字的大小 我们先看看程序的运行效果 一、先写好框架 #include void main() { } 二、然后定义我们需要的变量 int i,j;//只有两个参数 scanf("%d, %d",&i,&j); 三、这里就要写函数的部分 //这里的max是我们定义的函数名字,这个函数定义为int型表示我们最终要返回一个整形的数字 //括号里的两个表示形参,即我们要把我们在主函数中输入的两个数字放进去 但是还一个地方,要值得注意 当我们写了函数之后,要在主函数之前声明一遍, 这里就是告诉程序,我在下面的主函数中要用到我定义的这个函数 声明如下 一、常规方法比较大小 #include 这两个数字之间用空格隔开:\n"); scanf("%d%d",&i,&j); printf("%d\n",max(i,j));//声明完成之后,在这里调用我们写的函数,并且把我们输入的两个参数放进函数中
说起比较运算,肯定第一时间想到了C语言中关于比较的相关运算符 “>、<、!=、>=、<=、==”,那么要比较两个字符串是否相等是不是直接用“==”比较就行了。下面就来看看这种方法行不行? 这就要说下一字符串在C语言中比较特殊的一点,在C语言中处理一般的变量如整形、字符型、浮点型时,直接操作的是变量的值,比如 int a,b; a=b;在执行这行代码的时候,是将b的值拷贝一份然后复制给a。 而C语言在使用字符串的时候,是通过地址引用而不是值引用来操作的。 strcmp函数实际上是对字符的ASCII码进行比较,实现原理如下:首先比较两个串的第一个字符,若不相等,则停止比较并得出两个ASCII码大小比较的结果;如果相等就接着 比较第二个字符然后第三个字符等等 这个函数其实就是相当于把上面例程中对字符串每个字符独立比较方法的一个封装,内部函数实现方式类似于下面这样。 由于字符串在C语言中的处理比较特殊,所以C语言提供了一个专门操作字符串的库。
断言assert原型 void assert(int expression); assert宏的原型定义在<assert.h>中,其作用是先计算表达式expression的值为假(即为0),那么它就先向 放在函数参数的入口处检查传入参数的合法性; int resetBufferSize(int nNewSize) { //功能:改变缓冲区大小, //参数:nNewSize 缓冲区新长度 //返回值 保持原信息内容不变 nNewSize<=0表示清除缓冲区 assert(nNewSize >= 0); assert(nNewSize <= MAX_BUFFER_SIZE); ... } 在我们使用C语言 /C++做工程项目时,如果我们能在代码中合理的使用assert,能使我们创建更稳定、质量更好且不易于出错的代码;当需要在一个值为FALSE时中断当前操作的话就可以使用断言。 单元测试必须使用断言;另外除了类型检查和单元测试外,断言还提供了一种确定各种特性是否在程序中得到维护的极好的方法;
腾讯云物联网开发平台(IoT Explorer)为客户提供便捷的物联网开发工具与服务,助力客户更高效的完成设备接入,并为客户提供物联网应用开发及场景服务能力,帮助客户高效、低成本构建物联网应用……
扫码关注腾讯云开发者
领取腾讯云代金券