在C语言中创建变量其实就是 向内存申请空间,相应的就产生了地址,为了得到该变量的地址,我们需要使用到 & --取地址操作符。那我们该如何存放地址呢?答案是:存放在指针变量中。
#include<stdio.h>
int main()
{
int a = 10;
int* pa = &a;
//取出a的地址并且存储到指针变量a中
return 0;
}
pa 的类型是int* -----其中*说明pa是指针变量 ,int 说明pa指向的数据类型为int
那我们如何找到a的位置呢? 这个时候就需要用到解引用操作符 * 并且我们也可以通过*来改变变量的值,这样的运用比直接改变会更加的灵活。下面看如下代码:
int main()
{
int a = 100;
int* pa = &a;
*pa = 0;
return 0;
}
那指针变量的大小该如何计算呢?这里我们可以使用sizeof来进行计算,当然在不同的环境下,如32位机器、64位机器下,指针变量的大小是不一样的,我们来测试一下吧!
32位机器下(VS2020 x86 就是32位机器)
64位机器下
因此我们可以得出以下结论:
32位平台下地址是32个bit位,指针变量大小是4个字节
64位平台下地址是64个bit位,指针变量大小是8个字节
注意:指针变量的大小和类型是无关的,只要指针类型的变量,在相同的平台下,大小都相同
指针变量类型的意义
既然指针变量的大小和类型是无关的,那为什么还要有各种各样的指针类型呢?
下面我们来观察以下代码
在vs2022下调试 打开内存
我们可以发现对char*的指针解引用就只能访问一个字节,而int* 的指针解引用就能访问四个字节
所以指针类型决定了指针进行解引用操作的时候能够访问空间的大小
指针+-整数
我们可以看出,char*类型的指针变量+1跳过1个字节,而int*类型的指针变量+1跳过了4个字节
结论:指针的类型决定了指针向前或者向后走一步有多大(距离)
void*指针
在指针类型中有一种特殊的类型是void*类型的,可以理解为无具体类型的指针,这种类型的指针可以接受任意类型的地址,但是void* 类型的指针不能直接进行指针+-整数和解引用的操作。
const修饰指针变量
总结:const如果放在*的左边,修饰的是指针指向的内容,保证指针指向的内容不能通过指针来改变,但是指针变量本身的内容可变。
const如果放在*右边,修饰的是指针变量本身,保证了指针变量的内容不能修改,但是指针指向的内容,可以通过指针改变。
指针运算
指针+-整数
指针 - 指针
指针-指针的运算实现mystrlen
指针比较大小
野指针
就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)
assert断言
assert.h 头文件定义了宏assert(),用于在运行时确保程序符合指定条件,如果不符合,就报错终止运行。
my_strlen优化
总的来说assert就是用来保证指针的有效性
传值调用和传址调用
我们来看以下代码:写一个函数,交换两个整型变量的值
我们发现如果把a,b的值传过去,并没有实现两个数的交换。
这是因为:实参传递给形参的时候,形参会单独创建一份临时空间来接收实参,对形参的修改不影响实参。
传值调用并没有起作用,所以这个时候我们就需要用到传址调用。