1 C基本数据类型

C基本的数据类型说明:

2 字节序

测试代码:

#include <stdio.h>

typedef unsigned char *byte_pointer;

void show_bytes(byte_pointer start, int len)
{
int i; for (i = 0; i < len; i++) {
printf(" %.2x", start[i]);
}
printf("\n");
} int main(void)
{
int x = 0x01234567; show_bytes((byte_pointer)&x, sizeof(x)); return 0;
}

编译运行测试:

$ gcc endian.c
$ ./a.out
67 45 23 01

可以看出,当前我运行的机器是小端序。

3 结构体

参考:C语言技术天花板【结构体】一节课掌握_哔哩哔哩_bilibili

结构体中成员排列的规则:

  1. 结构体成员的内部偏移量(内部地址),要被这个成员的数据类型的大小整除。

    struct test {
    int a; /* [Byte][Byte][Byte][Byte] */
    char c; /* [Byte][0x00] */
    short s; /* [Byte][Byte] */
    };
    /* 结构体的内存大小 */
    sizeof(struct test) = 8; /* 结构体中的内存分布,可看出成员c后面填充了1Byte的0x00 */
    struct test test1 = {0};
    test1.a = 0x12345678;
    test1.c = 0xbb;
    test1.s = 0xccdd; (gdb) x /8bx &test1
    0x7fffffffe110: 0x78 0x56 0x34 0x12 0xbb 0x00 0xdd 0xcc
  2. 整个结构体的大小,必须是最大成员的size的整数倍,否则就需要在末尾填充空白字节。

    struct test {
    int a; /* [Byte][Byte][Byte][Byte] */
    char c; /* [Byte] */
    };
    /* 结构体的内存大小 */
    sizeof(struct test) = 8; /* 结构体中的内存分布,可看出成员c后面填充了3Byte的0x00 */
    (gdb) x /8bx &test1
    0x7fffffffe110: 0x78 0x56 0x34 0x12 0xbb 0x00 0x00 0x00
  3. 对于结构体中的结构体,按照结构体展开之后的内存对齐来处理。

    struct test1 {
    int a; /* [Byte][Byte][Byte][Byte] */
    short s; /* [Byte][Byte][0x00][0x00] */
    }; struct test {
    int a; /* [Byte][Byte][Byte][Byte] */
    char c; /* [Byte][0x00][0x00][0x00]*/
    struct test1 s;
    };
    /* 结构体的内存大小为16,根据规则1,成员c后面补充3Bytes的0x0,根据规则2,s.s成员后面补充2Bytes的0x0 */
    sizeof(struct test) = 16; /* 结构体中的内存分布 */
    struct test test1 = {0};
    test1.a = 0x12345678;
    test1.c = 0xff;
    test1.s.a = 0xaabbccdd;
    test1.s.s = 0x9988;
    (gdb) x /16bx &test1
    0x7fffffffe100: 0x78 0x56 0x34 0x12 0xff 0x00 0x00 0x00
    0x7fffffffe108: 0xdd 0xcc 0xbb 0xaa 0x88 0x99 0x00 0x00
  4. 认为指定特殊的对齐规则,使用#pragma pack(n)指定每个成员的其实地址,按照n来对齐,覆盖第一条规则。如果整个n比第一条规则对齐还要大,那么就取小的。

    #pragma pack(2)
    struct test1 {
    int a; /* [Byte][Byte][Byte][Byte] */
    short s; /* [Byte][Byte] */
    }; struct test {
    int a; /* [Byte][Byte][Byte][Byte] */
    char c; /* [Byte][0x00] */
    struct test1 s;
    };
    /* 结构体的内存大小为12,根据规则4,成员c后面补充1Bytes的0x0 */
    sizeof(struct test) = 12; /* 结构体中的内存分布 */
    struct test test1 = {0};
    test1.a = 0x12345678;
    test1.c = 0xff;
    test1.s.a = 0xaabbccdd;
    test1.s.s = 0x9988;
    (gdb) x /12bx &test1
    0x7fffffffe110: 0x78 0x56 0x34 0x12 0xff 0x00 0xdd 0xcc
    0x7fffffffe118: 0xbb 0xaa 0x88 0x99
    #pragma pack(8)
    struct test1 {
    int a; /* [Byte][Byte][Byte][Byte] */
    short s; /* [Byte][Byte] */
    }; struct test {
    int a; /* [Byte][Byte][Byte][Byte] */
    char c; /* [Byte][0x00] */
    struct test1 s;
    }; /* 规则1生效 */
    sizeof(struct test) = 16;
  5. 不使用任何对齐,直接存放数据的方式,使用#pragma pack(1)

    #pragma pack(1)
    struct test1 {
    int a; /* [Byte][Byte][Byte][Byte] */
    short s; /* [Byte][Byte] */
    }; struct test {
    int a; /* [Byte][Byte][Byte][Byte] */
    char c; /* [Byte] */
    struct test1 s;
    };
    /* 结构体的内存大小为11,各个成员之间不会填充0x0 */
    sizeof(struct test) = 11; /* 结构体中的内存分布 */
    struct test test1 = {0};
    test1.a = 0x12345678;
    test1.c = 0xff;
    test1.s.a = 0xaabbccdd;
    test1.s.s = 0x9988;
    (gdb) x /11bx &test1
    0x7fffffffe110: 0x78 0x56 0x34 0x12 0xff 0xdd 0xcc 0xbb
    0x7fffffffe118: 0xaa 0x88 0x99

C基本知识的更多相关文章

  1. 你必须知道的EF知识和经验

    注意:以下内容如果没有特别申明,默认使用的EF6.0版本,code first模式. 推荐MiniProfiler插件 工欲善其事,必先利其器. 我们使用EF和在很大程度提高了开发速度,不过随之带来的 ...

  2. MySQL高级知识- MySQL的架构介绍

    [TOC] 1.MySQL 简介 概述 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB公司开发,目前属于Oracle公司. MySQL是一种关联数据库管理系统,将数据保存在不同的表中,而 ...

  3. 学点HTTP知识

    不学无术 又一次感觉到不学无术,被人一问Http知识尽然一点也没答上来,丢人丢到家了啊.平时也看许多的技术文章,为什么到了关键时刻就答不上来呢? 确实发现一个问题,光看是没有用的,需要实践.看别人说的 ...

  4. java中的字符串相关知识整理

    字符串为什么这么重要 写了多年java的开发应该对String不陌生,但是我却越发觉得它陌生.每学一门编程语言就会与字符串这个关键词打不少交道.看来它真的很重要. 字符串就是一系列的字符组合的串,如果 ...

  5. [C#] C# 知识回顾 - 你真的懂异常(Exception)吗?

    你真的懂异常(Exception)吗? 目录 异常介绍 异常的特点 怎样使用异常 处理异常的 try-catch-finally 捕获异常的 Catch 块 释放资源的 Finally 块 一.异常介 ...

  6. [C#] C# 知识回顾 - 学会处理异常

    学会处理异常 你可以使用 try 块来对你觉得可能会出现异常的代码进行分区. 其中,与之关联的 catch 块可用于处理任何异常情况. 一个包含代码的 finally 块,无论 try 块中是否在运行 ...

  7. [C#] C# 知识回顾 - 学会使用异常

    学会使用异常 在 C# 中,程序中在运行时出现的错误,会不断在程序中进行传播,这种机制称为“异常”. 异常通常由错误的代码引发,并由能够更正错误的代码进行 catch. 异常可由 .NET 的 CLR ...

  8. [C#] C# 知识回顾 - 异常介绍

    异常介绍 我们平时在写程序时,无意中(或技术不够),而导致程序运行时出现意外(或异常),对于这个问题, C# 有专门的异常处理程序. 异常处理所涉及到的关键字有 try.catch 和 finally ...

  9. [.NET] C# 知识回顾 - Event 事件

    C# 知识回顾 - Event 事件 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/6060297.html 序 昨天,通过<C# 知识回顾 - ...

  10. [.NET] C# 知识回顾 - 事件入门

    C# 知识回顾 - 事件入门 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/6057301.html 序 之前通过<C# 知识回顾 - 委托 de ...

随机推荐

  1. HDMI输入SIL9293C配套NR-9 2AR-18的国产GOWIN开发板

  2. lattice crosslink开发板mipi核心板csi测试dsi屏lif md6000 fpga 常见问题解答

    1. 概述 CrossLink开发板,是用Lattice的芯片CrossLink 家族系列的,LIF-MD6000-6JM80I.该芯片用于桥接视频接口功能,自带2路MIPI硬核的功能,4 LANE  ...

  3. C内存操作API的实现原理

    我们在编写C代码时,会使用两种类型的内存,一种是栈内存,另外一种是堆内存,其中栈内存的申请和释放是由编译器来隐式管理的,我们也称为自动内存,这种变量是最简单而且最常用的,然后就是堆内存,堆的申请和释放 ...

  4. 《Effective C#》系列之(五)——优化集合的使用

    一.优化集合的使用 在<Effective C#>这本书中,优化集合的使用是其中一章的内容.以下是该章节的一些核心建议,以及使用C#代码示例说明: 使用泛型集合:泛型集合可以避免装箱和拆箱 ...

  5. eclipse 汉化语言包/中文补丁/简中设置/中英互换

    eclipse 汉化语言包/中文补丁/简中设置/中英互换 汉化很简单,使用eclipse内置的软件下载就可以,不需要下载压缩包 官方的说明 Open the install wizard with ' ...

  6. 力扣584(MySQL)-寻找用户推荐人(简单)

    题目: 给定表 customer ,里面保存了所有客户信息和他们的推荐人. 写一个查询语句,返回一个客户列表,列表中客户的推荐人的编号都 不是 2. 对于上面的示例数据,结果为:  解题思路: 本题最 ...

  7. 前沿分享|阿里云数据库资深技术专家 姚奕玮:AnalyticDB MySQL离在线一体化技术揭秘

    ​简介: 本篇内容为2021云栖大会-云原生数据仓库AnalyticDB技术与实践峰会分论坛中,阿里云数据库资深技术专家 姚奕玮关于"AnalyticDB MySQL离在线一体化技术揭秘&q ...

  8. JavaScript 如何实现一个响应式系统

    JavaScript 如何实现一个响应式系统 第一阶段目标 数据变化重新运行依赖数据的过程 第一阶段问题 如何知道数据发生了变化 如何知道哪些过程依赖了哪些数据 第一阶段问题的解决方案 我们可用参考现 ...

  9. UNO 的 SamplesApp.Skia.Gtk 丢失字体文件抛出空异常

    在运行 UNO 的 SamplesApp.Skia.Gtk 例子程序时,如果没有拷贝字体文件夹,导致字体丢失,将会在运行的时候抛出 NullReferenceException 空异常 抛出的异常堆栈 ...

  10. 如何参与 .NET 的开发和设计

    现在 dotnet 属于 dotnet 基金会,所有开发者都可以向 dotnet 贡献代码和参与 .NET 的设计,参与路线决策.本文来告诉大家一些基本玩法,带着小伙伴们入坑 注意哦,参与 dotne ...