该系列为本人的学习笔记,主要由本人整理书写而成。部分内容来自教材、视频课程等,不能保证完全原创性。
萌新的学习笔记,写错了恳请斧正。
# 传址调用与传址调用
传值调用就是指函数的参数为一个值,是把变量的值传递给了函数
在传值调用时,原变量不会受到函数的影响,因为传递时创建了形参
形参是实参的一份临时拷贝,参与到函数的运算中,而实参不受影响
传址调用则是将一个指针 (地址) 传递给函数参与运算
而这是,函数可以通过指针来找到实参的位置并加以修改
因此,传值调用可以对原变量产生影响
例如,我们可以利用传址调用来写一个交换两个变量的函数:
void Swap(int* p1, int* p2) | |
{ | |
int temp = 0; | |
temp = *p1; | |
*p1 = *p2; | |
*p2 = temp; | |
} |
# assert 断言
在 assert.h 头文件中定义了宏 assert (), 称为 assert 断言
assert 用于在运行时保证程序符合条件,如果不符合条件就立刻停止运行并报错
具体说是当函数运行到这一处时,就会检验 assert 中的表达式。如果表达式为假,就会在标准错误流里显示没有通过的表达式与其所处的文件名与行号。
比如说:
assert(p != NULL);
这一段代码就是在运行到这里时检验 p 是否为空指针,如果不是,就继续运行。

当程序写完检查确保没问题后,在包含 assert.h 头文件前加上一行就能关闭 assert 功能:
#define NDEBUG | |
#include <stdio.h> |
如果这么写再编译,编译器会自动跳过所有的 assert 断言语句,减少程序的运行时间
在 Visual Stodio 中,如果编译时选择 release 模式,就自动优化掉所有 assert 语句
# 二级指针
指针变量也是变量,那变量就有地址,所以就有指针的指针,即二级指针。
#include <stdio.h> | |
int main() | |
{ | |
int n = 0; | |
int* pn = &n; | |
int** ppn = &pn; | |
printf("n = %d\n", n); | |
printf("&n = %p\n", &n); | |
printf("pn = %p\n", pn); | |
printf("&pn = %p\n", &pn); | |
printf("ppn = %p\n", ppn); | |
return 0; | |
} |
其输出结果如下:

对二级指针,我们同样可以解引用
解引用一次就找到对应的一级指针,解引用两次就找到原变量:
*ppn 即 pn | |
**ppn 即 *pn 即 n |