1.值传递、地址传递、值返回、地址返回
1> 值传递:普通变量作为函数参数传递是单向的值传递,只是将实参的值复制一份给形参变量,形参的改变不会影响实参的值,因为所在内存空间不同
如果传递的是地址,被调函数使用指针接收,如果在被调函数中,没有更改指针指向空间中的内容,只改变指向,依然是值传递
2> 地址传递:指针、数组名作为函数参数传递,是地址传递,需要在被调函数中更改指针指向空间中的内容,形参内容的改变,实参也跟着改变
要求:主调函数中传递地址,被调函数中使用指针变量接收,被调函数中更改指针指向的内容
3> 值返回:普通变量通过函数返回值进行返回是单向的值返回,在主调函数中,该函数的返回值只能作为右值使用,不能被重新赋值
4> 地址返回:需要返回生命周期比较长的变量地址(全局变量、静态局部变量、堆区申请空间、主调函数地址传递的空间),该函数的返回值是一个左值,可以直接使用,也可以被重新赋值,被重新赋值后,被调函数中该空间中的内容也跟着改变
2.内存分区
1> 一个进程启动后,系统会为该进程分配4G的虚拟内存
2> 0--3G是用户空间,程序员写代码操作部分
3> 3--4G是内核空间,主要与底层驱动打交道
4> 所有进程会共享3--4G的内核空间,但是每个进程独立拥有0--3G的用户空间
5> 0--3G用户空间又被划分为三部分:栈区、堆区、静态区(全局区)
6> 全局区又分为四个段:.bss段、.data段、.ro段、.txt段
7> 应用层主要操作0--3G的用户空间,底层主要操作3--4G的内核空间
3.类型重定义(typedef)与宏定义(define)的区别
1> 宏定义只是单纯的替换,不做任何正确性检测,是一个预处理指令
2> 类型重定义,需要做正确性检测,是一条语句
3> 宏替换发生在预处理阶段,而类型重定义发生在编译阶段
4> 如果是对普通单个重命名没有问题,但是对指针重命名就有问题了
结构体大小
1> 一般而言,结构体的大小是各个成员变量所在内存之和
2> 特殊而言,结构体需要进行字节对齐,有利于数据偏移,和寻址功能
3> 字节对齐内容:
1、在结构体中的每个属性会根据自己所占内存大小,来设置起始存储位置,起始存储位置必须是自身类型的整数倍
2、在上面对齐的基础上,最后整体会进行一次对齐,整体的字节个数要是一个数据的整数倍,这个数据是系统字节对齐和结构体中最大成员所占字节的之间取最小值。min(系统对齐字节数,结构体中所占内存最大的字节数)
4> 在C语言中,一个空的结构体,所占内存大小为0字节