如何理解char型指针与int型指针的不同表现

来源:互联网 发布:网络攻防知识 编辑:程序博客网 时间:2024/06/15 07:34

这里是按照我的想法来猜测语言设计时的一些特性,如果有高人能进一步指点,不胜感激~


其实一直对字符串数组与字符串指针都抱有很多疑问,因为它用起来和整型指针相比完全不是一个风格。

比如char *str =”char test”;可以这样直接赋值

而整型int *a = {1,2,3}却完全不合理

我们可以很容易的理解int型指针,a就是指针是一个地址,&a就是指向的数据。然而str就是字符串”char test”,我们却取不到str的地址,&str却只能取到第一个字符。

所以到底怎么去理解char *与int*同为数组却不同的表现?

 

一.理解为什么char*指针取不到类似0x257GVB29这样的地址


这里建议大家先参考一下我之前写的一篇博客 图解数组指针与多维数组(附:为什么指针加一,地址不一定加一)

根据这个博客我们得出一个结论,逻辑内存中,每个字节对应一个地址,也就是每个字符对应一个地址,一个int型的变量由于是4个字节,就会对应4个地址。我们只有取到整型的首地址才能得到完整的int型数据。(如图m[0]就是int型的首地址,如果这时m[0]指向的是一个char,那么这个字符就是ASCII表 00000000 对应的字符)


 

 

这样,其实我们也应该可以理解,为什么int型的指针可以取到一个形如0x257GVB29这样的地址,而char型的指针却能取到一个字符。

因为对于一个char的地址,我们就可以或得对应的字符是什么,所以语言在设计的时候就让其显示出这个字符(这只是简单的猜测,可能会有更深一步的原因),而对于int的地址,我们只能知道这个int型数据第一个字节的内容,这个字节的数据可以说对我们没什么太大的意义,所以我们还是按照指针的方式来记录这个字节,这样比较容易去理解指针的意义。


(补充:我们看到一个int型对应4个字节,那么我们能不能只取到最后一个字节或者最后两个字节的数据?回答是可以的

   比如我们定义了一个int bTest = 0x123456;      通过(byte*)   和    (WORD*)强转再解引用即可

    #include <windows.h>    #define MEM_B(x) (*((byte*)(x)))    #define MEM_W(x) (*((WORD*)(x)))    int bTest = 0x123456;    int m = MEM_B((&bTest));/*m=0x56*/    int n = MEM_W((&bTest));/*n=0x3456*/

}

二.理解为什么char*可以这样char *str =”char test”直接赋值,int型的指针不能直接int *a = {1,2,3}赋值


给指针赋值就是让其指向一个地址。对于char *str = “abc”;本质是在内存常量区生成一个区域存放"abc"字符,而且这个区域是不可以修改的,不受用户控制,而str就是指向的这个地址,所以相当于const char *str,无法修改这个地址的变量。

我们进一步看,str指向的是一个字符串,所以给其赋值一个字符串是合理的,而且这些字符串中的字符都是连续的。而对于int型的指针,指向的是一个数,如果直接把好几个数赋值给指针,那么指针指向的应该是谁?如果你想说可以指向一堆连续存放的数,那么我告诉你,这个交给数组就可以了。你可以先声明一个数组,然后把数组的首地址给int*指针,这样就实现了让指针指向一个数组。

当然,C++在新标准中支持了{}赋值初始化,这样的赋值int a[] = {};是可行的,但是int型指针还是不支持的,这样设计也可能是为了避免混淆指针与数组。

0 0