C语言_地址与指针类型不兼容造成的影响

本文探讨了在C语言中,指针类型与所指向数据类型不匹配时可能导致的问题,通过实际例子和内存地址解析,解释了为什么错误指针会导致数据截断,并强调了地址与指针类型兼容性的必要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

地址与指针类型不兼容造成的影响

最近在复习C语言的语法,复习到指针的时候,看到自己的笔记写着“指针类型要与地址兼容”,换句话说就是“指针类型和所指数据的类型要一致”,当时还在旁边配着一小段代码。

int num01 = 18;
double num02 = 3.14;
int* point01 = &num01;		//√
double* point02 = &num02;	//√
double* point03 = &num01;	//×

假设我非要用double类型的指针指向int型的变量,“地址与指针类型不兼容”会造成什么影响呢?

接下来我们来写一个程序。

#include "stdio.h"

int main() {
    /*
     * 32位机,int类型占4个字节
     * 十六进制:0x 00 11 11 11
     * 十进制:1118481
     * 二进制:0b 00000000 00010001 00010001 00010001
     */
    int intNum = 1118481;
    int* intPoint = &intNum;
    //char型指针指向int型变量
    char* charPoint = &intNum;
    printf("===================\n");
    printf("sizeof(intPoint) = %d\n", sizeof(intPoint));
    printf("sizeof(charPoint) = %d\n", sizeof(charPoint));
    printf("===================\n");

    printf("intPoint: %p\n", intPoint);
    printf("charPoint: %p\n", charPoint);
    printf("===================\n");

    intPoint++;
    charPoint++;
    printf("intPoint++: %p\n", intPoint);
    printf("charPoint++: %p\n", charPoint);
    printf("===================\n");

    char charNum = 'a';
    //int型指针指向char型变量
    intPoint = &charNum;
    charPoint = &charNum;
    printf("intPoint: %p\n", intPoint);
    printf("charPoint: %p\n", charPoint);
    printf("===================\n");

    intPoint++;
    charPoint++;
    printf("intPoint++: %p\n", intPoint);
    printf("charPoint++: %p\n", charPoint);
    printf("===================\n");
    return 0;
}
/*
结果:
1、32位机,用4字节存储地址,所有sizeof都为4
sizeof(intPoint) = 4
sizeof(charPoint) = 4

2、两个指针都指向同一个地址,即0x 00 B3 F9 E0
intPoint: 00B3F9E0
charPoint: 00B3F9E0

3、因为int类型占4个字节,char类型占1个字节。
所以int型指针的增量为4字节,char型指针为1字节
intPoint++: 00B3F9E4
charPoint++: 00B3F9E1

4、两个指针都指向同一个地址,即0x 00 B3 F9 E0
intPoint: 00B3F9BF
charPoint: 00B3F9BF

5、因为int类型占4个字节,char类型占1个字节。
所以int型指针的增量为4字节,char型指针为1字节
intPoint++: 00B3F9C3
charPoint++: 00B3F9C0
*/

在这里插入图片描述

由上可得,程序可以编译并且运行成功。重点是int型的指针和char型指针同时指向同一个变量时,最初指针变量的值(即指向的地址)都是一样的,但是执行完自增操作后值就不同了。

为何呢?

指针的两个语义:一是内存的基地址,即变量存放的地址;二是指向数据的类型,即变量所占的内存空间。

如我刚刚演示的程序,在32位的环境下,int型占4个字节,所以int型的指针自增就是以4个字节为增量。


接下来,我们再举一个列子来说明,类型不兼容的影响。

32位机,int类型占4个字节
我们用8个字节,即2int型或者8char型来实验
    
int型数字1:
十六进制:0x 41 42 43 44
十进制:0d 1094861636
二进制:0b 01000001 01000010 01000011 01000100
    
int型数字2:
十六进制:0x 45 46 47 48
十进制:0d 1162233672
二进制:0b 01000101 01000110 01000111 01001000
    
8char型变量与其对应的二进制、十进制
'A'  --> 0b 01000001  -->  0d 65
'B'  --> 0b 01000010  -->  0d 66
'C'  --> 0b 01000011  -->  0d 67
'D'  --> 0b 01000100  -->  0d 68
'E'  --> 0b 01000101  -->  0d 69
'F'  --> 0b 01000110  -->  0d 70
'G'  --> 0b 01000111  -->  0d 71
'H'  --> 0b 01001000  -->  0d 72
#include "stdio.h"

void printChar(char* start, char* end);

void printInt(int* start, int* end);


int main() {
    printf("=================================\n");
    char charArr[8] = { 'H', 'G', 'F', 'E', 'D', 'C', 'B', 'A' };
    printf("sizeof(charArr)/sizeof(char) = %d\n", sizeof(charArr) / sizeof(char));
    printf("sizeof(charArr)/sizeof(int) = %d\n", sizeof(charArr) / sizeof(int));
    printf("=================================\n");
    //char型指针指向char型变量
    char* charPoint01 = charArr;
    //int型指针指向char型变量
    int* intPoint01 = charArr;

    printChar(charPoint01, charPoint01 + sizeof(charArr) / sizeof(char));
    printInt(intPoint01, intPoint01 + sizeof(charArr) / sizeof(int));
    printf("=================================\n");

    int intArr[2] = { 1162233672, 1094861636 };
    printf("sizeof(intArr)/sizeof(char) = %d\n", (sizeof(intArr)) / sizeof(char));
    printf("sizeof(intArr)/sizeof(int) = %d\n", sizeof(intArr) / sizeof(int));
    printf("=================================\n");
    int* intPoint02 = intArr;
    char* charPoint02 = intArr;
    printChar(charPoint02, charPoint02 + 8);
    printInt(intPoint02, intPoint02 + sizeof(charArr) / sizeof(int));
    printf("=================================\n");
    return 0;
}

void printChar(char* start, char* end) {
    while (start < end) {
        printf("%c   ", *start);
        start++;
    }
    printf("\n");
}

void printInt(int* start, int* end) {
    while (start < end) {
        printf("%d   ", *start);
        start++;
    }
    printf("\n");
}

/*
结果:
=================================
sizeof(charArr)/sizeof(char) = 8
sizeof(charArr)/sizeof(int) = 2
=================================
H   G   F   E   D   C   B   A
1162233672   1094861636
=================================
sizeof(intArr)/sizeof(char) = 8
sizeof(intArr)/sizeof(int) = 2
=================================
H   G   F   E   D   C   B   A
1162233672   1094861636
=================================
*/

在这里插入图片描述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nm6ZYIjq-1651587040629)(E:\Blog\C语言\地址与指针类型不兼容造成的影响.assets\image-20220503220039270.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OHt2ZmpH-1651587040629)(E:\Blog\C语言\地址与指针类型不兼容造成的影响.assets\B77D75137C78F5B3187117B349520427.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XxWR3Rv2-1651587040629)(E:\Blog\C语言\地址与指针类型不兼容造成的影响.assets\3BE22090F5F814F2283131A8054E7D8F.png)]

由此得出,我们将2个int型的数据,其在内存中的存储占8个字节,int型指针会一次读取4个字节,可以正常显示2个int型变量。

但是如果我们错误地将char型指针指向int型变量,char型数据在内存中占1个字节,char型指针一个只会读取1个字节的数据,因为就会将2个int型变量输出成8个char型变量,造成数据截断。


综上所述,指针类型和其所指向的数据类型要一致,即“地址和指针类型兼容”,否则在进行“指针操作”时会出现诸多问题。

注:如有错误,敬请指正!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

窝在角落里学习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值