P20:#define offsetof(TYPE, MEMBER) ((size_t)&((TYPE*)0)->MEMBER)
1、
offsetof
宏是 C 语言中用于计算结构体成员相对于结构体起始地址的偏移量的宏定义。这个宏的定义如下:
#define offsetof(TYPE, MEMBER) ((size_t)&((TYPE*)0)->MEMBER)
这个宏定义的工作原理如下:
TYPE*
是一个指向TYPE
结构体的指针。(TYPE*)0
将整数 0 转换为TYPE
类型的指针。这里 0 是一个空指针常量,转换成TYPE
类型的指针后,它指向的是结构体的起始地址。((TYPE*)0)->MEMBER
使用箭头操作符->
访问结构体的成员MEMBER
。由于TYPE*
指针指向地址 0,这实际上是在计算MEMBER
在TYPE
结构体中的偏移量。(size_t)&((TYPE*)0)->MEMBER
取MEMBER
成员的地址并强制转换为size_t
类型,这样得出的就是MEMBER
相对于结构体起始地址的偏移量。
通过这个宏,你可以在运行时获取结构体成员的偏移量,这对于编写低级代码或者处理结构体布局非常有用。
size_t:
size_t
是一种无符号整数类型,用于表示对象的大小和内存地址。它是标准 C 库中的一种类型,size_t
的大小取决于平台的架构(32 位或 64 位),并且它能存储最大的内存地址值,因此它通常与平台的指针大小匹配。在 32 位系统中,size_t
通常是 4 字节(32 位),在 64 位系统中,通常是 8 字节(64 位)。
X86和X64的区别:
X86指的是支持32位的指令集架构处理器,最初由英特尔在1978年发布的 intel 8086,这个系统主要为X86结尾所以简称X86,而X86有16位和32位,现今大多数用的是32位处理器。
X64指的是支持64位的指令集架构处理器,最初由AMD在2003年发布的AMD 64 支持64位的处理器由来,后续英特尔为了支持X64所以也推出 intel X64。
联合体和结构都要做数据对齐,对齐的位数取决于系统是32位还是64位
32位默认操作的最小单元是4个字节,64位默认操作的最小单元是8个字节
这里在代码前加上#pragma pack(4)
可以实现强制4字节对齐
P21:const
在c中也可以这样间接的修改const变量的值
用const修饰形参的时候,不能更改它修饰的值:
以下函数定义是会报错的
P22:fork()
#include <stdio.h>
#include <unistd.h>
int main() {
fork() || fork();
printf("Hello ");
return 0;
}
分析:
最初的进程(P0)调用第一个fork()。这会创建一个子进程(P1)。
P0: 第一个fork()返回非0(父进程的返回值),所以fork()的结果为真,fork()后的第二个fork()不会执行。
P1: 第一个fork()返回0(子进程的返回值),所以fork()后的第二个fork()会执行。
P1调用第二个fork(),创建另一个子进程(P2)。
P1: 第二个fork()的结果返回非0,执行printf("Hello ")。
P2: 第二个fork()返回0,执行printf("Hello ")。
总结
P0: 执行printf("Hello ")。
P1: 执行printf("Hello ")。
P2: 执行printf("Hello ")。
总共有3个进程执行printf("Hello "),所以最终输出"Hello "三次。
P23:指针引用
P24:调用几次构造函数
C++中的class的应用_c++ class用法-CSDN博客
疑问:C++的string类 和 class的关系是什么?
答疑:C++的string
类和class
的关系在于string
是一个具体的类,而class
是定义类的关键字。string
类是C++标准库中的一部分,它是一个封装了字符串操作的类,提供了许多功能,比如动态管理字符串内存、字符串拼接、查找等。而class
是用来定义自定义类型的工具,可以用来创建自己的类,包括string
这样已有的类。简单来说,string
是通过class
定义的。
疑问:C++中struct和class的区别
有一点特殊的是,当class定义时,如果没有string name这种复杂的定义则其他简单定义就不会初始化
题目:
这里MyClass a[4] 创建了4个类的对象,所以执行了四次构造函数
这里MyClass *p[5] 创建了5个指向类的对象的指针,因为只是指向类对象的指针所以并没有创建对象,所以不会执行构造函数
P25:求二进制值中1的个数
P26:判断一个数是否是2的n次方
P27运算重载函数:
P29:变量置位,清零操作
P30:sizeof运算符中的表达式:
sizeof(i++);//这个表达式不会把i++后的值赋给i,因为它是运算符,不是函数,它只会判断计算完的值是什么类型,不会去赋值
P31:指针+整数
0x801000是整形常量,而P1和P2是指针,他们类型不匹配,编译器一定会报错,所以我们需要在前面加上指针类型转换。
32位系统与64位系统各数据类型所占空间大小_32位系统和64位系统下数据类型的占用空间相同吗-CSDN博客
P32 volatile关键字:
P33 c++中空类占用的内存大小
不管是不是空类,所有类都可以实例化(就是分配内存空间)
在空类中会隐含的添加一个字节
P34:如果a是一个数组,那&a和a的区别是什么
&a相当于一个二级指针,&a+1相当于加了5(int *)
P35:如何不使用第三个变量来交换两个变量的值:
方法一:
方法二:
记忆方法:永远是三个a^b,前面的被赋值数永远是两个夹一个
技巧:2夹1,三异或