字符指针的特别之处

  如果我们对一个非字符的指针进行操作,方法是这样的:

  定义:int a=7; int *p=&a; 或者 int a=7; int *p; p=&a; 或者 int a=7; int *p; *p=a;

    输出指针的内容(即所指向空间的地址):cout<<p<<endl;
  输出指针所指的内容(即指针内容所描述地址空间中的内容):cout<<*p<<endl;

  指针对于字符的处理却有些特殊,和前面的非字符的指针输出处理要分开理解。

  比如,我们定义一个 char a='A'; char *p=&a;  如果我们调用上面非字符指针的输出方式,结果如下:
  方式1 cout<<p<<endl; 结果 A####(#表示乱码,不可识别) 并不是地址
  方式2 cout<<*p<<endl; 结果 A 这和非字符的指针情况一样,输出指针指向的内容
  而且我们直接操作 cout<<&a<<endl; 结果和方式1的结果是完全相同的

  为什么方式1输出的不是地址呢?这里有一个特殊的处理,虽然这里的p的内容确确实实是一个地址,但是cout操作字符指针的话,它遇到地址,就会直接去寻找这个地址所指向的内容,并把它的空间里的机器数按照字符的规则转化成字符输出,直到遇到“/0”这个操作符才停止。所以我们直接输出p的时候,它先输出‘A’然后再继续读取后面的内存空间知道遇到“/0”,显示结果是“A+乱码”。

  你肯定会说,为什么要这样呢,这样多不方便呀,其实这么做是有目的的,而且恰恰就是为了方便才这么设置的。因为这样就可以很容易的处理字符串了,而处理字符串是我们在计算机中用得很多的操作。

  比如我们第一个字符串数组 char a[]="mantou"; a[]在内存中在7个字节,而不是6个,因为在mantou字符串后面还隐藏有一个“/0”,这时我们用 char *p=a; (这里不用&a是因为,a[]是一个数组,数组名a本身就是一个指针常量) 输出操作 cout<<p<<endl; 这里就不会输出地址,而是直接输出整个mantou字符串,很方便。如果我们 cout<<*p<<endl; 结果显示的是m,因为p是指向数组的首元素的地址的,就是指向这里的储存m的空间的地址,所以取p的内容(*p),只能输出一个m。

  虽然通常情况下我们是不需要了解我们的数据地址的,但我也顺便说说,怎么得到字符指针的地址,也可以方便大家对内存地址的分配再做更深入的研究。

  char a='A';  如果这里直接输出 cout<<&a<<endl; 当然是不能输出地址的,原理上面已经说过了,cout遇到字符型地址就会转换成字符输出。我们可以用指针p先取得a的地址(char *p=&a;),但是这样用 cout<<p<<endl; 也并不能得到地址呀,做个小技巧,首先我们知道p中的内容本身就是地址,但是因为它是字符串,我们又不能直接输出它,所以呀,我们可以把指针里的内容(记载的是一个地址数据)强制转化成整型再输出 cout<<(int)p<<endl; 呵呵,这样就得到了这个指针里的内容——十进制型的地址,而我们知道,地址是用十六进制表示的,形式是 0x######## 0x后面加8位十六进制数,我们把我们先得到的十进制地址按照地址的表示形式用流操作转化成十六进制就可以了。代码如下:

cout<<"0x"<<setfill('0')<<setw(8)<<setiosflags(ios::uppercase)<<hex<<(int)p<<dec<<setfill(' ')<<endl;  //流控制实现十六进制地址输出
注意不要忘了 #include<iomanip.h> 这个头文件

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值