C/C++学习笔记五(结构体、字符与字符串)

本文探讨了C/C++中结构体的内存分布、对齐规则以及空结构体在C和C++中的差异。同时,文章详细阐述了字符串、字符数组之间的区别,sizeof与strlen的区别以及strcpy与memcpy的使用注意事项。通过对结构体和字符串的深入理解,有助于优化代码和避免潜在问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

结构体

C语言中复杂的数据结构都需要使用结构体表示,在这里说一下结构体的使用要点。

结构体内存分布以及对齐问题

编译器在为结构体分配内存时,并不会分配和所有成员数据长度和恰好相等的内存空间,而是会考虑到计算机cpu的读取性能,对结构按照某个模数(alignment modulus)进行对齐。

例如结构体中拥有int (4个字节),char(1个字节)两个变量,但在使用sizeof进行大小输出时,并不是简单的各个成员数据的大小相加(4+1 = 5字节),而是经过编译器对齐后的8个字节

struct TestStruct {

    int a;
    char b;
}testStruct;

printf("%p \n",&testStruct); // 8

出现这样的结果,是因为编译器在对数据成员的内存地址上进行了对齐。而这种对齐是与计算机CPU相关的一种优化技术,计算机系统中对基本的数据类型在内存中的存放位置有限制,他们会要求这些数据的内存地址是某一个数的k倍,这个k值也被称为对齐模数(alignment modulus)

空结构体c与c++的sizeof得出的长度是不一致的

这是一个有意思的问题,对于无成员的结构体长度,c与c++的长度却是不一致的。空结构体的长度在c中为0,而c++中则为1。

struct NoPropertyStruct {

}noPropertyStruct;

printf("%lu \n",sizeof(noPropertyStruct)); // C时输出0,C++时输出1

查看C、C++两者的汇编代码

C`main:
    0x100000f20 <+0>:  pushq  %rbp
    0x100000f21 <+1>:  movq   %rsp, %rbp
    0x100000f24 <+4>:  subq   $0x20, %rsp
    0x100000f28 <+8>:  leaq   0x62(%rip), %rax          ; "sizeof(TestStruct) = %lu \n"
->  0x100000f2f <+15>: xorl   %ecx, %ecx                ;对ecx做异或,也就是ecx置为0
    0x100000f31 <+17>: movl   %ecx, %edx
    0x100000f33 <+19>: movl   $0x0, -0x4(%rbp)
    0x100000f3a <+26>: movl   %edi, -0x8(%rbp)
    0x100000f3d <+29>: movq   %rsi, -0x10(%rbp)
    0x100000f41 <+33>: movq   %rax, %rdi
    0x100000f44 <+36>: movq   %rdx, %rsi
    0x100000f47 <+39>: movb   $0x0, %al
    0x100000f49 <+41>: callq  0x100000f5e               ; symbol stub for: printf
    0x100000f4e <+46>: movl   $0x1, %ecx
    0x100000f53 <+51>: movl   %eax, -0x14(%rbp)
    0x100000f56 <+54>: movl   %ecx, %eax
    0x100000f58 <+56>: addq   $0x20, %rsp
    0x100000f5c <+60>: popq   %rbp
    0x100000f5d <+61>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值