三:指针变量类型的意义
指针变量的大小和类型无关,只要是指针变量,在同一个平台下,大小都是一样的。那为什么还要有各种各种的指针类型呢?请看下方讲解。
1、指针的解引用
对比一下以下两个代码,来观察内存的变化。
代码一:
代码二:
通过调试可以看出,代码一会将a的4个字节全部改为0,但是代码2只是将a的第一个字节改为0.
结论:指针的类型决定了对指针解引用的时候有多大的权限(即一次能操作几个字符)。
例如:char*的指针解引用就只能访问一个字节,而int*的指针解引用就能访问四个字节。
2、指针+-(加减)整数
看下方代码,观察地址的变化。
通过代码我们可以看出,char*类型的指针变量+1,跳过一个字节,int*类型的指针变量+1跳过了4个字节,这就是指针变量的类型差异带来的变化。
结论:指针的类型决定了指针向前或者向后走一步有多大距离。
3、void*指针
在指针类型中有一种特殊的类型是void*类型,可以理解为无具体类型的指针(或者叫泛型指针),这种类型的指针可以用来接受任意类型的地址。但是也有局限性,void*类型的指针不能直接进行指针的+-(加减)和解引用的运算。
例如:
在上面的代码中,将一个int类型的变量的地址赋值给一个char*类型的指针变量。编译器给出了警告。因为类型不兼容。但是使用void*类型就不会出现这样的问题。
例如:
void*的局限性:
这里可以看出,void*类型的指针可以接收不同类型地址,但是无法直接进行指针运算。
void*其他的用处:
一般void*类型的指针是使用在函数参数的部分,用来接受不同类型数据的地址。这样可以使得一个函数来处理多种类型的数据。
四:const修饰指针
1、const修饰变量
变量是可以修改的,如果把变量的地址交给一个指针变量,通过指针变量也可以修改这个变量。但是如果我们希望一个变量加上一些限制,使变量的值不能被修改。这时需要使用const。
疑问:既然变量被const修饰,此时的变量不能被修改,那改变量是常量吗?
我们知道,vs2022不支持变长数组,我们可以通过数组来说明被const修饰的变量是不是常量。
代码如下:
但是如果我们绕过m,使用m的地址,去修改m就能做到了。
从上面的代码中可以看出,被const修饰的变量再赋值是不允许的,但是使用变量的地址在可以给变量赋值。
如果我们拿到了被const修饰变量的地址,也不能修改数据,该怎么做呢?请看下方解答。
2、const修饰指针变量
一般来说const修饰指针变量,可以放在*的左边,也可以放在*的右边,意义是不一样的。
const放在*的左边:
const放在*的右边:
总结:
(1)const如果放在*的左边,修饰的是指针指向的内容,保证指针指向的内容不能通过指针来改变,但是指针变量本身的内容可变。
(2)const放在*的右边,修饰的是指针变量本身,保证了指针变量的内容不能修改,但是指针指向的内容可以通过指针改变。