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 ...
随机推荐
- 2.go语言入门----变量类型、声明变量、数组、切片
基本变量类型 介绍几种基本的变量类型:字符串.int.float.bool package main import ( "fmt" ) // 列举几种非常基本的数据类型 func ...
- Flannel和Calico网络插件工作流程对比
Flannel和Calico网络插件对比 Calico简介 Calico是一个纯三层的网络插件,calico的bgp模式类似于flannel的host-gw Calico方便集成 OpenStac ...
- 你们一般都是怎么进行SQL调优的?MySQL在执行时是如何选择索引的?
前言 过年回来的第二周了,终于有时间继续总结知识了.这次来看一下SQL调优的知识,这类问题基本上面试的时候都会被问到,无论你的岗位是后端,运维,测试等等. 像本文标题中的两个问题,就是我在实际面试过程 ...
- 剑指 Offer 65. 不用加减乘除做加法 + 位运算
剑指 Offer 65. 不用加减乘除做加法 Offer_65 题目描述 题解分析 java代码 package com.walegarrett.offer; /** * @Author WaleGa ...
- PAT-1132(Cut Integer )数的拆分+简单题
Cut Integer PAT-1132 #include<iostream> #include<cstring> #include<string> #includ ...
- LeetCode-重建二叉树(前序遍历+中序遍历)
重建二叉树 LeetCode-105 首次需要知道前序遍历和中序遍历的性质. 解题思路如下:首先使用前序比遍历找到根节点,然后使用中序遍历找到左右子树的范围,再分别对左右子树实施递归重建. 本题的难点 ...
- 使用python模块plotdigitizer抠取论文图片中的数据
技术背景 对于各行各业的研究人员来说,经常会面临这样的一个问题:有一篇不错的文章里面有很好的数据,但是这个数据在文章中仅以图片的形式出现.而假如我们希望可以从该图片中提取出数据,这样就可以用我们自己的 ...
- SQL 性能起飞了!
直接上干货 对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及order by涉及的列上建立索引. 应尽量避免在 where 子句中对字段进行 null 值判断,创建表时NULL是默认值 ...
- 记客户端WebBrowser控件修改版本的问题
保留在本地电脑的一篇记录,第二条描述是在网上看来的,忘记在哪看的了,也就没注明出处,望见谅. 1.Winform内置浏览器控件的底层调用与系统IE浏览器的底层调用相同. 2.IE8 对渲染引擎做了很大 ...
- 掌握HTTP原理
URI和URL URI的全程为Uniform Resource identifier,即统一资源标志符,URL的全称 Universal Resource Locator 即统一资源定位符 在目前的互 ...