入门客AI创业平台(我带你入门,你带我飞行)
博文笔记

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

创建时间:2015-12-26 投稿人: 浏览次数:2664

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


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

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

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

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

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

 


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

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


 

 

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

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

(补充:我们看到一个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 *str = “abc”;本质是在内存常量区生成一个区域存放"abc"字符,而且这个区域是不可以修改的,不受用户控制,而str就是指向的这个地址,所以相当于const char *str,无法修改这个地址的变量。为什么str在打印的时候就变成了“char test”?这可以理解为是语言层面的处理。

char* cstr = "123";//从常量区分配一个空间
char* cstr1 = "123";
//cstr[0] = "e";//会触发异常,因为cstr指向的是常量区的地址,不允许修改
//char[] cstr = "123";//这种情况是从栈区分配一个空间

cout << "打印字符串:" << endl;
cout << cstr<<endl;
cout << cstr1 << endl;
cout << endl;

cout << "打印地址:" << endl;
cout << "cstr指针地址:"<<&cstr << endl;//指针地址
cout << "cstr字符串首地址:" << (void *)(cstr) << endl;//字符串首地址,需要强制转换否则输出字符串
cout << "cstr字符串首地址:" << static_cast<const void *>(cstr) << endl;//一种更合适的强转

cout << "cstr1指针地址:" << &cstr1 << endl;
cout << "cstr1字符串首地址:" << static_cast<const void *>(cstr) << endl;

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

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

关于字符串的更多理解与案例可以参考:

声明:该文观点仅代表作者本人,入门客AI创业平台信息发布平台仅提供信息存储空间服务,如有疑问请联系rumenke@qq.com。