C语言之指针(二)

前言:

        大家好,经过上一篇C语言之指针(一)中,我们了解到了内存和地址以及指针变量、地址等一系列的指针知识,这些知识点作为指针学习的前备工作,这种知识更像是一种“内功”一样,知道了这些概念后,也更加有利于我们对于接下来的指针学习。这里将附上“C语言之指针(一)”的链接,供大家参考。C语言之指针(一)-CSDN博客

一、指针变量的大小

        在前面我们了解到,32位机器假设有32根地址总线,每根地址线出来的电信号转换成数字信号后是1或者0,那我们把32根地址线产生的2进制序列当作是一个地址,那么一个地址就是32个比特位,也就是需要4个字节大小才能够存储。(一个字节=8个比特位)

        如果指针变量是用来存放地址的,那么在32位机器下,指针变量的大小必须得4个字节才能够存储地址。

        同理,在64位机器下,有64根地址总线,那么一个地址就是64个比特位,存储起来就是8个字节的空间。

代码如下:

#include <stdio.h>
//指针变量的⼤⼩取决于地址的⼤⼩
//32位平台下地址是32个bit位(即4个字节)
//64位平台下地址是64个bit位(即8个字节)
int main()
{
 printf("%zd\n", sizeof(char *));
 printf("%zd\n", sizeof(short *));
 printf("%zd\n", sizeof(int *));
 printf("%zd\n", sizeof(double *));
 return 0;
}

x86版本运行结果如下:

x64版本运行结果如下:

结论:

(1)32位平台下地址是32个bit位,指针变量⼤⼩是4个字节。

(2)64位平台下地址是64个bit位,指针变量⼤⼩是8个字节。

(3)注意指针变量的⼤⼩和类型是无关的,只要指针类型的变量,在相同的平台下,大小都是相同的。

二、指针变量类型的意义

        首先,指针变量的大小和类型 无关,只要是指针变量且在同一个平台下,其大小是一样的,那么我们为什么还要去了解指针变量的类型呢?接下来我们深度解析一下。

3.1指针的解引用

接下来,我们就对两段代码来解析一下:

        首先对于代码一来说,:其中创建的指针p的类型为“int*”类型,而在内存中的解引用操作时,“int*”类型一次可以访问4个字节,如下图所示:

        由此可见,对于“int*”类型的解引用,一次改变的是4个字节,也就是将变量n的值改为0.

        对于代码二来说,其中创建的指针p的类型为“char*”类型,而在内存中的解引用操作时,“char*”类型一次可以访问1个字节,如下图所示:

        在内存中,一个int类型的变量有32位,只改变其中一个字节,即把上图中填充的部分改为0。

        结论:指针的类型决定了对指针解引⽤的时候有多大的权限(⼀次能操作几个字节)。
比如: char* 的指针解引用就只能访问⼀个字节,而 int* 的指针的解引用就能访问四个字节。

3.2指针的加减(+/-)

先从一段代码入手:

#include <stdio.h>
int main()
{
	int n = 10;
	char* pc = (char*)&n;
	int* pi = &n;

	printf("%p\n", &n);
	printf("%p\n", pc);
	printf("%p\n", pc + 1);
	printf("%p\n", pi);
	printf("%p\n", pi + 1);
	return 0;
}

代码运算结果:

        由此可知,对于一个char*类型的指针,其加一则地址会向后跳过一个字节,对于一个int*类型的指针,其加一则地址会向后跳过4个字节。

        结论:指针加减的结果最终还是指针,即:指针+/-整数=指针。

四、const修饰的指针

4.1const修饰变量

        变量是可以修改的,如果把变量的地址交给一个指针变量,通过指针变量也可以修改这个变量,但是如果我们希望能够对这个指针变量加上一些限制,这就是const的作用。

还是以代码为例:

        以上代码中,m的本质是变量,是可以修改的,但是如果加上const这一限制条件,就使得m不可被随意修改。可如果非要改变m的值,那就要绕道而行,通过其地址的方法来改变。代码如下:

        如此一来,m的值就可以被修改了,但是这里我们要思考一个问题,既然一开始要给m加上const来修饰,其目的就是为了m不被改变,但是我们发现通过地址也可以轻松的修改m的值,这样似乎前面的const就好像是有些多此一举了,这显然是不合理的,所以我们应该让p即使拿到m的地址也不可修改其值。

4.2const修饰指针变量

        上述中我们了解到,const可以修饰变量,那么同理,const也可以修饰指针变量,其修饰方法有两种:

(1)const int* p / int const * p----const在*的前面

(2)int* const p----const在*的后面

        对于两种const的修饰,其效果自然是不尽相同。

        首先是const在“*”之前,它修饰的是*p,也就是指针指向的内容,它可以保证指针指向的内容不能通过指针来改变,但是可以修改指针指向的方向,也就是指针变量本身可以改变。

        其次是const在“*”的右边,这时const修饰的是p也就是指针本身,它可以保证指针p指向的方向不发生改变,但是却可以改变通过解引用p所指向的内容。

接下来通过一段代码来直观理解这两种修饰方式:

#include<stdio.h>

int main()

{
	int n = 10;
	int m = 20;
	const int* p = &n;
	*p = 30;//当const在*之前时,修改其指向的内容时会报错
	p = &m;//当const在*之前时,修改其指向的方向时,不报错。
	return 0;
}

#include<stdio.h>

int main()
{
	int n = 10;
	int m = 20;
	int* const p = &n;
	*p = 30;//当const在*右边时,可以改变其指向的内容。
	p = &m;//但如要修改其指向的方向,就会报错
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值