电子商城网站建设与维护,学做网站是什么,海南建设官方信息网站,html制作手机网站前言
在“走进指针世界#xff08;上卷#xff09;”中#xff0c;我们已经说过#xff1a;什么是指针、内存和地址#xff0c;指针的使用、声明、初始化#xff0c;取地址运算符、解引用运算符以及这两者关系#xff0c;还有指针赋值。
在正式使用指针进行各种代码的…前言
在“走进指针世界上卷”中我们已经说过什么是指针、内存和地址指针的使用、声明、初始化取地址运算符、解引用运算符以及这两者关系还有指针赋值。
在正式使用指针进行各种代码的编写之前在这篇“走进指针世界下卷”里让我们再了解一些指针的重要的前置知识吧。 指针变量的大小
指针变量有大小吗 答案是有的。我们知道sizeof是一个操作符 其作用是返回一个对象或类型所占的内存字节数。就像整型变量、字符型变量等可以用sizeof计算大小一样指针变量也可以这样计算大小
#includestdio.hint main()
{int a 10;int* p a;printf(%zd\n, sizeof(p));return 0;
}
在vs2022的x8632位环境下我们可以得出这样的运行结果 如果改成x6464位环境就是这样的运行结果 所以我们知道指针变量p的大小就是4或8个字节。
指针变量大小与指向类型的关系
p是指向整型变量的指针变量那指向字符型变量的指针变量有多大呢我们可以再用同样的方式进行观察
char a a;
char* p a;
printf(%zd\n, sizeof(p));
return 0;
x8632位环境下结果 x6464位环境下结果 可以看到指向字符型变量的指针变量的大小同样是4或8个字节。我们可以继续去观察指向其他类型变量的指针变量的大小最终会发现都是4或8个字节取决于环境。
为什么呢 明白这个问题我们必须知道地址是怎么产生的。
计算机中的编址是通过硬件设计完成的。
计算机中有很多的硬件单元硬件单元之间互相协同工作而协同工作需要相互之间能够进行数据传递。硬件之间相互独立它们的通信方式是用“线”连起来。CPU和内存之间有大量的数据交互所以这两者也用线连起来。
32位机器有32根地址总线每根线只有两态表示为0或1电脉冲有无那么一根线可以表示两种含义32根线就可以表示2^32种含义每种含义可以表示一个地址。
既然把32根地址线产生的2进制序列当作一个地址那么一个地址就是32个bit位需要4个字节来存储。所以指针变量的大小就是4个字节。
在这个分析的过程中我们可以看出指针变量的大小与该指针指向的数据类型确实是无关的只与是32位环境还是64位环境有关。 指针变量类型的意义
既然指针变量的大小都是4或8个字节那么你可能会好奇指针变量类型的意义在哪呢现在我们就来了解一下指针变量类型的意义。
对于解引用的意义
第一个方面的意义在于解引用指针类型的意义决定了在对指针解引用时有多大的权限或者说一次能操作几个字节 *pa0之后 从内存窗口我们可以看出在对指向int类型的指针变量pa解引用并赋值0时我们把4个字节00为一个字节都该为了0。
如果将同样的动作施加于一个指向char类型的指针变量会发生什么 *pa0之后 可以看到我们只能操作一个字节。 所以当指针变量指向的类型不同即指针变量的类型也不同时解引用的权限可能是不同的。 对于指针加减整数的意义
指针变量的类型还决定了指针加减一个整数时实际移动的字节数。或者通俗点说指针向前或向后走一步有多大距离。 我们在vs的x86下用%p打印观察地址。发现同一个整型变量我们用两个不同类型的指针存储它的地址在加1后地址的变化不相同。我们知道一个内存单元为1个字节每个字节有自己的编号即地址所以pa1加了4个字节而pc1加了1个字节。
其实pa1时加的并不是整数1而是1*sizeof(int)pc1时加的是1*sizeof(char)。 void*指针
有一种特殊的指针类型void*指针也就是无具体类型的指针也叫泛型指针。
这种指针有其优缺点。
优点
它的优点就是既然是泛型指针在接收一个地址的时候无需局限于某个类型的地址可以把任意类型数据的地址交给它。比如下面这个代码是合法的
int a 10;
void* p a;
当我们遇到不知道具体类型的地址又需要用指针存储时void*指针就可以派上用场。
缺点
但是它也有自己的缺点就是无法直接进行指针的加减整
数运算和解引用运算因为它不知道要操作几个字节。
int a 10;
void* p a;
printf(%d\n, *p);//会报错 const修饰指针
有时我们不希望指针指向的内容被修改那么我们就可以使用const对其进行修饰。
还记得const的用法吗
int a 100;
a 200;
在这个代码中我们把a的值改变了。
const int a 100;
a 200;//会报错
而我们用const修饰变量a时a变成了“常变量”本质上还是个变量但是不能被修改。
那么现在我们再看一个代码 我们用const修饰变量n的声明时我们本意是希望n的值不会被修改而通过指针我们却间接改掉了变量n的值那么我们怎样才能达到我们的预期呢 当我们在指针变量p的声明时用cconst进行修饰就无法再通过刚才的方式修改n的值而是会报错了。 const与*的前后关系 在声明一个指针变量并想要用const进行修饰时我们需要注意的一点是const和*的先后关系。因为当const放在*前面时无法被修改的是指针指向的内容当const放在*后面时无法改变的是指针的指向 注意const放在*前面时在int前还是后都是一样的效果 而当const放在*后面时才会有根本的改变 还有一种情况当我们在*的前后都放上const那就变成了指向和指向的内容都无法修改 总之可以根据我们不希望被修改的内容来决定const的用法并且在需要使用const的时候不要吝啬使用因为它可以在我们不小心修改了不应该修改的内容时及时给出警告。 那么到此为止“走进指针世界”就结束了后面我还会持续更新指针相关的更多内容希望大家发现错误可以向我指正^_^