C语言小知识(基于Linux)——个人笔记,不定时更新
一、switch case语法,在case中定义变量时,需要在case的有效范围内使用花括号包起来,否则会编译报错;
switch (name){
case "zhangSan":{
int age = 13;
break;
}
case "liSi":{
int age = 14;
break;
}
default:{
break;
}
}
二、规定结构体以n字节对齐
在C语言结构体中,字节对齐方式默认为最大类型字节对齐;比如:
struct Class{
char age;
int id;
}class;
这个结构体有两个成员,分别为1字节的age与4字节的id(32位编译时);实际占用了5个字节的空间,但是此时sizeof(class) == 8;因为最大的成员 id 占了4个字节,所以会以4字节对齐;age就会补充3个字节的保留位来字节对齐。
但是在数据流的处理中,为节约资源,一般每个字节甚至每个bit都需物尽其用;所以上述结构只需要5字节有效空间;
此时就可以使用#pragma pack(n)来进行n字节对齐;
#pragma pack(1)
struct Class{
char age;
int id;
}class;
#pragma pack()
现在sizeof(class)就会等于5了;age只占1字节;在结构体之后加上#pragma pack()是为了限制1字节对齐的范围;#pragma pack()之后的数据结构又会以默认最大成员类型来进行字节对齐;
三、结构中按bit定义变量
可以在定义变量时,变量名之后,分号;之前 加上 : n 来规定此变量占用的位数;
#pragma pack(1)
struct ZhangSan{
unsigned char gender_flag : 1;
unsigned char age : 7;
unsigned short height : 6;
unsigned short weight : 6;
unsigned short id : 4;
}zhangSan;
#pragma pack()
此时gender_flag 成员与age 成员就共用一个字节的空间,height 与 weight 与 id 共用两个字节的空间;sizeof(zhangSan) == 3;
四、数据大小端
1.位序
有如下结构:
struct ZhangSan{
unsigned char gender_flag : 1;
unsigned char age : 7;
}zhangSan;
其中 gender_flag 与 age 共用了一个字节(8bit)的空间,一个占1bit,一个占7bit;但是bit占的位置却是与平台相关的;就有可能出现如下两种排列情况:

为了解决这种差异化,一般规定传输时的位序都为大端;即在基本类型里声明多个位域时,每个位域看做一个整体,先声明的排在前面,后声明的排在后面;在声明结构体时就可以依据本机的位序来声明位域,从而在接收数据流时能顺利的取出每一个位域。
Linux系统中一般可以通过判断是否定义了宏 __LITTLE_ENDIAN_BITFIELD 与 __BIG_ENDIAN_BITFIELD 来区分当前的位序定义;
若这两个宏同时都没有定义,还可以添加 对字节序的判断来得出本机的位序定义,如下:
#if !defined(__LITTLE_ENDIAN_BITFIELD) && !defined(__BIG_ENDIAN_BITFIELD)
#if (__BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__)
#define __LITTLE_ENDIAN_BITFIELD
#elif (__BYTE_ORDER__==__ORDER_BIG_ENDIAN__)
#define __BIG_ENDIAN_BITFIELD
#endif
#endif
struct ZhangSan{
#if defined(__LITTLE_ENDIAN_BITFIELD)
unsigned char gender_flag : 1;
unsigned char age : 7;
#elif defined(__BIG_ENDIAN_BITFIELD)
unsigned char age : 7;
unsigned char gender_flag : 1;
#endif
}zhangSan;
加了如上修饰之后,即可保证接收到的大端数据流中的位域都能成功的映射到本机所定义的位域;
2.字节序
在数据流跨平台的传递中,经常会遇到大小端不对齐的情况;比如一个int数据在大端机器中的存储方式是高位在前,低位在后,
比如0x33224411在内存中的存放方式就是先存0x33,再存0x22,以此类推。如下:
buf[0] = 0x33;
buf[1] = 0x22;
buf[2] = 0x44;
buf[3] = 0x11;
而小端平台就刚好相反,是低位在前,高位在后;同样的数据0x33224411在小端中的存放方式就是先存0x11,再存0x44,以此类推。如下:
buf[0] = 0x11;
buf[1] = 0x44;
buf[2] = 0x22;
buf[3] = 0x33;
为了使数据统一,所以一般规定了在网络中传输的数据都以大端模式传递,收到数据之后再把数据从大端模式转为本机的模式即可正常使用;
在linux系统的#include <endian.h>中提供了一系类字节序转换的函数:
#include <endian.h>
// 将主机字节序转换为大端字节序
uint16_t htobe16(uint16_t host_16bits);
uint32_t htobe32(uint32_t host_32bits);
uint64_t htobe64(uint64_t host_64bits);
// 将主机字节序转换为小端字节序
uint16_t htole16(uint16_t host_16bits);
uint32_t htole32(uint32_t host_32bits);
uint64_t htole64(uint64_t host_64bits);
// 将大端字节序转换为主机字节序
uint16_t be16toh(uint16_t big_endian_16bits);
uint32_t be32toh(uint32_t big_endian_32bits);
uint64_t be64toh(uint64_t big_endian_64bits);
// 将小端字节序转换为主机字节序
uint16_t le16toh(uint16_t little_endian_16bits);
uint32_t le32toh(uint32_t little_endian_32bits);
uint64_t le64toh(uint64_t little_endian_64bits);
C语言小知识(基于Linux)——个人笔记,不定时更新的更多相关文章
- Go 语言开发的基于 Linux 虚拟服务器的负载平衡平台 Seesaw
负载均衡系统 Seesaw Seesaw是由我们网络可靠性工程师用 Go 语言开发的基于 Linux 虚拟服务器的负载平衡平台,就像所有好的项目一样,这个项目也是为了解决实际问题而产生的. Seesa ...
- Go语言核心36讲(Go语言基础知识一)--学习笔记
01 | 工作区和GOPATH 从 Go 1.5 版本的自举(即用 Go 语言编写程序来实现 Go 语言自身),到 Go 1.7 版本的极速 GC(也称垃圾回收器),再到 2018 年 2 月发布的 ...
- Go语言核心36讲(Go语言基础知识四)--学习笔记
04 | 程序实体的那些事儿(上) 还记得吗?Go 语言中的程序实体包括变量.常量.函数.结构体和接口. Go 语言是静态类型的编程语言,所以我们在声明变量或常量的时候,都需要指定它们的类型,或者给予 ...
- Go语言核心36讲(Go语言基础知识六)--学习笔记
06 | 程序实体的那些事儿 (下) 在上一篇文章,我们一直都在围绕着可重名变量,也就是不同代码块中的重名变量,进行了讨论.还记得吗? 最后我强调,如果可重名变量的类型不同,那么就需要引起我们的特别关 ...
- Go语言核心36讲(Go语言基础知识二)--学习笔记
02 | 命令源码文件 我们已经知道,环境变量 GOPATH 指向的是一个或多个工作区,每个工作区中都会有以代码包为基本组织形式的源码文件. 这里的源码文件又分为三种,即:命令源码文件.库源码文件和测 ...
- Go语言核心36讲(Go语言基础知识三)--学习笔记
03 | 库源码文件 在我的定义中,库源码文件是不能被直接运行的源码文件,它仅用于存放程序实体,这些程序实体可以被其他代码使用(只要遵从 Go 语言规范的话). 这里的"其他代码" ...
- Go语言核心36讲(Go语言基础知识五)--学习笔记
05 | 程序实体的那些事儿(中) 在前文中,我解释过代码块的含义.Go 语言的代码块是一层套一层的,就像大圆套小圆. 一个代码块可以有若干个子代码块:但对于每个代码块,最多只会有一个直接包含它的代码 ...
- 小知识-为什么Linux不需要磁盘碎片整理
转载至:http://beikeit.com/post-495.html 简单译文: 这段linux官方资料主要介绍了外部碎片(external fragmentation).内部碎片(inter ...
- 语言小知识-Java ArrayList类 深度解析
· 问题 1:ArrayList 的 size 和 capacity 怎么理解? 如果把 ArrayList 看作一个杯子的话,capacity 就是杯子的容积,也就是代表杯子能装多少东西,而 siz ...
随机推荐
- 玩遍博客网站,我整理了 Hugo 及其流行的风格主题
搭建博客网站是个人进入互联网世界的最常见方式之一.伴随着网站技术的发展,如何搭建博客网站已经变得非常容易了.当然,你可以选择诸如 新浪博客.CSDN.博客园 之类的大型网站,快速创建依赖于大平台的个人 ...
- FTP服务器搭建以及上传下载的学习
首先需要搭建FTP服务步骤如下: 1.在win7上先开启ftp服务:这里点击确定后,可能会要等一会儿,完成后有时系统会提示重启 2.打开 计算机-->管理--> 在这里我们可以看见 ...
- 通过CollectionUtils工具类判断集合是否为空,通过StringUtils工具类判断字符串是否为空
通过CollectionUtils工具类判断集合是否为空 先引入CollectionUtils工具类: import org.apache.commons.collections4.Collectio ...
- Git 提交获取项目与提交项目 记录
首先去git官网下载版本安装:https://git-scm.com/downloads 在自己生产免密令牌,安装后用git程序导出. 1.自己在桌面或者某盘创建一个文件夹,在文件夹右键找到 GIt ...
- 设置ViewPager 自动滑动时间,速度 方便展示动画
ViewPager.setCurrentItem(position),即使已设置动画,但是没有动画效果 原因:因为ViewPager滑动之前的时间间隔太短,可以通过反射,去修改ViewPager自动滑 ...
- HDU1067 Gap
题目: Let's play a card game called Gap. You have 28 cards labeled with two-digit numbers. The first d ...
- Eric Python IDE 论文数据图片生成
Python编写,基于跨平台的Qt GUI工具包,集成了高度灵活的Scintilla编辑器控件. 大括号匹配,错误突出显示和可配置语法突出显示. 拼写检查库的集成 内置Python调试器,包括支持调试 ...
- mysql操作和详解
温馨提示 mysql安装包里面:mysqld是服务端,mysql是客户端. mysqld其实是SQL后台程序(也就是MySQL服务器),它是关于服务器端的一个程序,mysqld意思是mysql dae ...
- JS逆向-抠代码的第四天【手把手学会抠代码】
今天是md5巩固项目,该项目比昨天的复杂一些,但方法思路是一样的. 今天的目标:https://www.webportal.top/ 打开网站,填入账号密码(密码项目以123456做测试).点击登录抓 ...
- vim下在插件emmet
试了很多种方法,结果都没有用,最后找到了完美的解决方法! 1.方式1 1.1下载emmet并解压 1.2 cd /home/debian8/Downloads/emmet-vim-master/plu ...