C语言-不同类型的指针变量的区别

目录

1.引言

2.指针变量的类型有两个意义:

1.指针类型决定了指针变量访问空间的能力

2.指针类型决定了指针的步长

3.应用


1.引言

指针是什么?指针是内存的编号,称为地址也称为指针。当我们说“变量pa是个指针”的时候,这个地方指针指的是指针变量,指针变量pa是一个用来存放地址的变量(如下代码)

int a = 10;
int* pa = &a;  创建指针变量pa,pa存放整型a的地址

char b = 'h';
char* pb = &b; 创建指针变量pb,pb存放字符型b的地址

指针的定义方式是 “类型 + * ”,例如:

int* 类型的指针存放 int 类型变量的地址

char* 类型的指针存放 char 类型变量的地址

pa和pb的指针类型不同(" int* "和" char* "),这是定义指针时决定的,那么这两种类型的指针还有什么本质上的区别吗?


2.指针变量的类型有两个意义:

1.指针类型决定了指针变量访问空间的能力

进行解引用操作的时候能访问到几个字节

下面给两例对比说明:

例1:

int main()
{
	int a = 16519441;  16进制形式是00fc1111
	int* p1 = &a;
	*p1 = 10;  解引用修改a的值
	printf("a = %d\n", a);
	return 0;
}

因为指针变量p1的类型是int*,所以他进行解引用操作时可以访问4个字节的空间 

如下图。F10调试,打开内存观察(具体操作步骤:调试-窗口-内存),在内存窗口输入p1,自动显示p1中存放的地址(0x008FFE24),注意在内存中每一个字节都有自己的地址,这里地址所指向内存中存放的值是以16进制的形式呈现的【一个地址(0x008FFE24)所指向的一个字节的内存空间里面存放着2位16进制数(11)】【解释上一句话:我们从进制转化中可知,两位16进制数可以用8位2进制数表示,在内存中数字是以二进制形式存放的,8位二进制数在内存中占8bit空间,即1个字节空间,对应16进制的两位(11)】。因此,整型变量a(16进制形式为:00 fc 11 11)占4个字节,即从地址0x008FFE24到地址0x008FFE27的这一段内存空间,存放了整型变量a。

继续按F10调试,第491行执行,p1解引用访问到4个字节的空间,并将其修改为10(16进制表示为00 00 00 0a),如下图

 例2:

int main()
{
	int a = 16519441;  16进制形式是00fc1111
	char* p2 = (char*)&a;
	*p2 = 10;  解引用修改a的值

	printf("a = %d\n", a);
	return 0;
}

因为指针变量p2的类型是char*,所以他进行解引用操作时可以访问1个字节的空间

如下图。还是和例1相同的操作,F10调试,打开内存观察,在内存窗口输入p2,观察p2地址及其向后的四个地址(0x012FF794-0x012FF797),表示存放整型变量a(16进制表示:00 fc 11 11)

继续按F10调试,第491行执行,p2解引用访问到1个字节的空间,并将其修改为10(16进制表示为0a),如下图

可以看到,p2只有1个字节的访问权限,他只能修改内存空间中1个字节的数据,即0x012FF794指向的1个字节空间,后面的3个字节(11 fc 00)都没有被修改,因此printf以整型打印a的结果就是16519434(00 fc 11 0a

总结:虽然p2也保存了整型变量a的地址,和p1中保存的地址是一模一样的,但因为p2的类型是char*,而p1的类型int*,他们进行解引用操作时访问空间的能力不同,导致解引用对整型变量a修改时产生不同的效果

2.指针类型决定了指针的步长

指针变量加或减一个整数,指针向后或向前移动的字节数

上述比较抽象,直接看例子解释:

int main()
{
	int a = 10;
	int* pa = &a;  创建int*类型的指针变量pa
	printf("pa = %p\n", pa);        打印pa
	printf("pa + 1 = %p\n", pa+1);  打印pa+1

	char b = 'h';
	char* pb = &b; 创建char*类型的指针变量pb
	printf("pb = %p\n", pb);        打印
	printf("pb + 1 = %p\n", pb+1);  打印pb+1

	return 0;
}

pa + 1 = 0019FCC0 + 4 = 0019FCC4;   整型指针+1,向后移动4个字节(跳过一个整型)

pb + 1 = 0019FCACB + 1 = 0019FCAC;   字符型指针+1,向后移动1个字节(跳过一个字符型)

同理,double型指针+1,向后移动8个字节(跳过一个double型)


3.应用

1.假设有个整型数组arr1,arr1是数组中第一个整型元素的地址,arr1+1的意义是什么;

2.假设有个字符型数组arr2,arr2是数组中第一个字符型元素的地址,arr2+1的意义是什么;

3.下面代码输出的结果是什么;

int main()
{
	int a = 0x33445566;
    char *pc = (char*)&a;
    *pc = 0;
    printf("%x\n", a);//以16进制的形式打印整数
    return 0;
}

答:

1.数组中元素在内存中的存放是连续的,"arr1+1"是整型数组arr1中第二个整型元素的地址

2."arr2+1"是字符型数组arr2中第二个字符型元素的地址

3.输出33445500

  • 18
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值