目录
前言:
1、指针变量与地址
int a=10;//创建 一个int 型变量,并且将这个变量赋值为10
printf("%p",&a);
int a =10;这行代码表面意思是创建一个整型变量,并且将这个变量赋值为10,还有一层意思,因为 int这个整型占用4个字节,所以开辟4个字节,用来存储数据10.
通过 & 操作符可以得到变量的地址,此时再通过printf函数进行打印操作,注意,对于地址类型的占位符是用 %p
内存地址延伸信息:
根据前文给int类型开辟了4个字节用来存储数据,每个字节都有自己的地址,那么为什么通过 %p占位符得到的只有一个地址呢? 这个时候我们来监视一下内存。
2:指针类型的意义
1:指针类型可以决定指针解引用的时候访问多少字节(指针的权限)
short * 解引用后可以访问2个字节
float *解引用后可以访问4个字节
double *解引用后可以访问8个字节
2:指针在进行运算时,会根据不同的指针类型进行对应的步长调整。
3:野指针
3.1未初始化
int main() {
int* ptr; //未初始化指针ptr
*ptr = 200; //将一个没有初始化的指针解引用,会让编译器报错。
printf("%d", *ptr);
return 0;
}
3.2 越界访问
3.3 返回局部变量的地址
int* test() {
int a = 10;
return &a;
}
int main() {
int* p = test();
printf("%p\n", p);
*p = 20;
printf("don\n");
printf("%d\n", *p);
return 0;
}
问题在于,当函数 test
执行完毕并返回时,其中的局部变量 a
将会失效,其内存空间可能会被其他程序使用。因此,当你在 main
函数中解引用指向 a
的指针 p
时,指针 p
实际上指向的是一个无效的内存地址,这会导致未定义行为,从而可能产生随机值。
4:const 修饰指针
当一个变量被const修饰后,就会变长常变量,本质上还是变量,但是无法被修改,所以叫做常变量,当const修饰一个指针的时候,会有3种修饰情况,这两种情况 以 * 作为区分。
4.1:const 出现在 * 号 前:
const int * p = &a ;
const 出现在 * 后左边,这样的作用是限制到了 *p,但是p本身是不会收到限制,p仍然可以指向其他合法区间。
4.2 :const出现在 * 号后:
4.3:const 出现在 * 左右
5:指针的关系运算
5.1 指针 + - 整数
5.2 指针-指针
5.3 指针的关系运算
6:断言 assert
assert()实际上是一个宏,需要包含头文件<assert.h> 中使用,具体的使用规则如下,assert (条件表达式)
7:函数传值调用 vs 传址调用
#1 size_t
是 C 和 C++ 编程语言中定义的一种无符号整数数据类型,该类型在不同的编译器和平台上可能具有不同的长度。通常,size_t
被用作用于内存分配、数组和缓冲区尺寸等情况下的存储空间大小的计数器。在 32 位系统上,size_t
的长度通常为 32 位(4 字节),而在 64 位系统上,它通常为 64 位(8 字节)。由于 size_t
是无符号的,因此它只能存储非负整数值
接下来写一个简单的交换函数,通过监视功能来实际体验一下传值跟传址的不同之处。