前言
本博文主要是对ip地址,主机地址,mac地址学习进行的一个记录,以方便后面查阅。
博文写于2021-04-26 16:55:06,于2024-02-06编辑进行博文排版。
ip地址和主机地址
就像身份证,主机名就是你的姓名,让别人可以看到并知道你是谁;IP地址就像是身份证号,别人喊你不可能喊你的身份证号吧?其他电脑要识别你只能是通过IP地址。其实就是主机名是让其他用电脑的人能知道你是谁?IP地址是让其他的电脑知道你在哪里
MAC地址
MAC地址也叫物理地址、硬件地址或链路地址,由网络设备制造商生产时写在硬件内部。IP地址与MAC地址在计算机里都是以二进制表示的,IP地址是32位的,而MAC地址则是48位的。MAC地址的长度为48位(6个字节),通常表示为12个16进制数,每2个16进制数之间用冒号隔开,如:08:00:20:0A:8C:6D就是一个MAC地址,其中前6位16进制数08:00:20代表网络硬件制造商的编号,它由IEEE(电气与电子工程师协会)分配,而后3位16进制数0A:8C:6D代表该制造商所制造的某个网络产品(如网卡)的系列号。只要你不去更改自己的MAC地址,那么你的MAC地址在世界是惟一的。
如有多块网卡,可以查看到不同网卡的MAC地址。
额外补充
日志部分就先到这!接下来,是一些个人平时整理的c++要点概要,如有需要可以进行阅读!
结构体
- 第一种是最基本的结构体定义, 其定义了一个结构体 A。
struct A { int a;};
- 第二种则是在定义了一个结构体 B 的同时定义了一个结构体 B 的变量 m。
struct B { int b;}m;
- 第三种结构体定义没有给出该结构体的名称, 但是定义了一个该结构体的变量 n, 也就是说,若是想要在别处定义该结构体的变量是不行的, 只有变量 n 这种在定义结构体的同时定义变量才行。
struct { int c;}n;
- 第四种结构体定义在第一种结构定义的基础上加了关键字
typedef
, 此时我们将struct D{int d}
看成是一个数据类型, 但是因为并没有给出别名, 直接用 D 定义变量是不行的。 如D test;
,不能直接这样定义变量 test。 但struct D test;
可行。
typedef struct D { int d;};
- 第五种结构体定义在第四种结构体定义的基础上加上了别名 x, 此时像在第四种结构体定义中说得那样, 此时的结构体 E 有别名 x, 故可以用 x 定义 E 的结构体变量。 用 E 不能直接定义, 需要在前面加
struct,
如struct E test;
。
typedef struct E { int e;}x;
- 第六种结构体定义在第五种的基础上减去了结构体名, 但是若是直接使用 y 来定义该结构体类型的变量也是可以的。 如
y test;
。 (常用)
typedef struct { int f;}y;
sizeof
- sizeof 是操作符, 在编译阶段就获得结果, strlen 是函数调用, 在运行阶段才获得值。
- sizeof 求数组时, 大小等于数组元素个数*每个元素的大小(其中, 计算字符串数组是需要计算结束符’\0’, 这是与 strlen 的区别, strlen 不计算最后的’\0’, 如 char a[] = “abcd”; 表示的是一个字符串, 字符串会有一个’\0’作为结尾, 所以整体存储 a 的大小为 5, 但是如果用 strlen判断 a 的长度不会计算末尾的’\0’, 所以是 4) ,但是当数组是函数的形参时会将会降为指针,在 32 位系统中无论什么指针类型都是占 4 个字节。
- sizeof 运算符算引用类型时, 是所引用的类型的大小; sizeof 指针得到的是指针本身的大小
大小端
大端和小端存储指的是对于多字节数据的表示方式。
- 在大端存储中, 如 ARM 平台, 数据的高字节保存在内存的低地址中, 而数据的低字节保存在内存的高地址中(低位高地址, 高位低地址 );
- 而在小端存储中, 如 X86、 x86-64 平台、 80X86, 数据的低位保存在内存的低地址中, 而数据的高位保存在内存的高地址中(低位低地址, 高位高地址) 。
例如,对于十六进制数 0x1234 , 高位 0x12 , 低位 0x34(内存地址: 高->低) , 数组中, 大端存储的表示方式是 0x12 0x34, 而小端存储的表示方式是 0x34 0x12。 结构体中, 先声明的是低地址, 后声明的是高地址, 如果先声明 m, 则大端存储, m 是 0x12。
nm命令
nm 命令查看汇编代码, 由 GNU C++汇编生成的改编后的函数名规则如下:
- 每个改编后的函数名(除了 main 函数) 以 2 个下划线( __) 开始, 后跟字母 Z、一个数值和函数名在跟着形参列表的编码(没有形参就不用了)。字母 Z 后的数值表示函数名称中字符的个数。
例如,函数 int donothing(char a, int b, float &c, double &d)在它的函数名中有 9 个字符, 所以改编后名字的前缀是__Z9。 然后, 接着跟着函数名, 后跟有它的形参列表的编码。 在函数 donothing的形参列表中 char 表示为 c, int 表示为 i, float &表示为 Rf, double &表示为 Rd。 所以最
终汇编形成的函数名为: __Z9donothingciRfRd
fork()系统调用的特性
fork()系统调用是 Unix 下以自身进程创建子进程的系统调用, 一次调用, 两次返回, 如果返回是 0, 则是子进程, 如果返回值>0, 则是父进程(返回值是子进程的 pid) 。 还有一个很重要的东西是, 在 fork()的调用处, 整个父进程空间会原模原样地复制到子进程中, 包括指令, 变量值, 程序调用栈, 环境变量, 缓冲区, 等等。
指针与const
- const A * 等价 A const * 。
- 允许用 A * 赋值 A const * 。
- 允许用 A* * 赋值 A const* const * 。
- 不允许用 A* * 赋值 A const* * 。