C++字符指针的特殊

2023-11-05

 如果我们对一个非字符的指针进行操作,方法是这样的: 
注意:int* p;则p[i]等价于*(p+i)


  定义: 
    (1)int a=7; int *p=&a; 或者 
    (2)int a=7; int *p; p=&a; 或者 
    (3)int a=7; int *p; *p=a; 

  (1)这样定义的原因是因为等号两边的类型必须匹配,int *p=&a; 等号左边定义的是一个指针,指针的内容是地址,所以等号右边也应该是地址,&a就是取空间a的地址; 
    (2)int *p; p=&a; 为什么不是 *p=&a 而是 p=&a; 因为在定义的时候“*”只是说明p是一个指针,而p也是一个变量,不过是储存地址的一种特殊的变量,对于变量使用,我们都是直接使用它的名字,就好象,我们定义个常量 const a=7; 我们要调用它的时候直接使用a就可以了,并不需要带上 const 修饰,这里也一样,用指针变量时并不需要带上“*”; 
    (3)而第三种情况中的 *p=a;中的“*”和第二种里面是不同的,这里的“*”是取内容符,与之相反的是取地址符“&”,分析一下,第三种情况中,等号左边是*p表示对指针p取内容,它的内容指向内存中的某个已经在开始通过 int *p; 定义好的空间里(比较确切一点的说法是,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<<endl<<"0x" 
     <<setw(8)<<setiosflags(ios::right)<<setfill('0') 
     <<setiosflags(ios::uppercase)<<hex<<(int)p<<endl; 

注意不要忘了 #include<iomanip.h> 这个头文件哦  

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++字符指针的特殊 的相关文章

随机推荐

  • 龙书笔记(12)

    chap 12 设计一个灵活的Camera类 主要是创建一个相机类 Camera 1 Camera类的设计 右向量 right vector 上向量 up vector 观察向量 look vector 位置向量 position vect
  • Linux高性能网络编程:TCP底层的收发过程

    今天探索高性能网络编程 但是我觉得在谈系统API之前可以先讲一些Linux底层的收发包过程 如下这是一个简单的socket编程代码 int main fd socket AF INET SOCKET STREAM 0 bind fd lis
  • Linux如何(永久)关闭SElinux和firewalld防火墙

    本文基于Linux上CentOS 7版本进行演示 目录 一 关闭SElinux 1 临时关闭 2 永久关闭 二 关闭防火墙 firewalld服务 1 查看防火墙状态 2 关闭防火墙 一 关闭SElinux 1 临时关闭 使用setenfo
  • CAN接受和发送失败的原因有哪些---之前调试MCP2515驱动时,数据一直发不出去,三个发送邮箱都被占满.至今未解决,读寄存器-总线错误

    0 CAN总线错误分析与解决 讲的最精辟的放在最前面 我们知道CAN总线上的每个节点往总线上发送数据的同时会同时读取总线上的数据 并与自己发送的数据作对比 CAN仲裁 CAN总线错误分别有发送和接收错误计数 计数达到一定的累计以后就会产生C
  • InnoDB存储引擎 3文件

    参数 查看information schema下的GLOBAL VARIABLES查找参数 但是在mysql8 0 21没有这张表格 视图 出错 SELECT FROM global variables WHERE VARIABLE NAM
  • 【华为OD统一考试A卷

    华为OD统一考试A卷 B卷 新题库说明 2023年5月份 华为官方已经将的 2022 0223Q 1 2 3 4 统一修改为OD统一考试 A卷 和OD统一考试 B卷 你收到的链接上面会标注A卷还是B卷 请注意 根据反馈 目前大部分收到的都是
  • count(1)、count(*)与count(列名)的执行区别

    执行效果 1 count 1 and count 当表的数据量大些时 对表作分析之后 使用count 1 还要比使用count 用时多了 从执行计划来看 count 1 和count 的效果是一样的 但是在表做过分析之后 count 1 会
  • Python计算水仙花数

    水仙花数是指一个 3 位数 它的每个位上的数字的 3次幂之和等于它本身 例如 1 3 5 3 3 3 153 方法1 用 for循环 控制1000以内的3位数 依次求出该3位数中的个十百位 判断是否是水仙花数 方法2 x y z分别表示一个
  • 如何创建并发布你的angular组件库

    本例创建一个天气组件 ng new weatherwidget createApplication false 选择不要路由 选择scss cd weatherwidget 用vs code打开本项目 创建组件库weather ng gen
  • 给学习C语言的朋友推荐一本好书!

    友情提示 本图书链接指向第二书店的图书详细页面 近期公司要开展技术学习及培训 推荐使用了两本教材 一本是清华大学出版社的 计算机科学概念 第8版 人民邮电出版社出版了该书的第7版 另一本则是电子工业社出版的Programming in C
  • drools规则引擎的在项目中的使用手记

    需求 按照登录用户的会员等级 和签到周期 根据一定的计算规则送积分 由于之前都是通过if else去做的控制 规则变更的时候可能需要重新调整代码甚至发布服务 由于不想再每次规则变更后需要调整代码 于是最近在确认方案 于是最好找到了规则引擎
  • python3 条件语句

    条件语句 if 判断条件 执行语句 else 执行语句 if 判断条件1 执行语句1 elif 判断条件2 执行语句2 elif 判断条件3 执行语句3 else 执行语句4 python 并不支持 switch 语句 如果多个条件需同时判
  • uniapp打包app,对接华为厂商,实现unipush离线消息推送

    今天终于可以抽出点时间 来记录一下这几天心塞的心情 上周公司派过来一个活 说是使用uniapp制作一个app 同时要实现在线消息推送和离线消息推送 啥话没说就揽了下来 不过说实在的 从来没有开发过app 好歹会点vue 可想而知 接下来的几
  • arduino基础25个实验代码

    arduino基础25个实验代码 双色LED灯项目源码 int redPin 11 红色LED引脚 int greenPin 10 绿色LED引脚 int val 0 PWM输出值 void setup pinMode redPin OUT
  • 华为打造狼性团队的22条军规

    打造狼性团队的22条军规 领导者要读3遍 打出来 贴到桌子上 做老板的 无不对华为公司的狼性团队推崇有加 华为的狼性文化之所以如此成功 三大因素缺一不可 一是具有诱惑力的薪酬 这是自驱力 二是内部竞争机制 这是推动力 三是执行力文化 这是牵
  • 类的静态成员变量为什么不能再h文件类外初始化

    h文件 class Image public static void AddProtoType Image iamge Prototype nsize iamge private static Image Prototype 10 stat
  • pandas练习题

    按要求创建Dataframe df 并通过分组得到以下结果 以A分组 求出C D的分组平均值 以A B分组 求出D E的分组求和 以A分组 得到所有分组 以字典显示 按照数值类型分组 求和 将C D作为一组分出来 并计算求和 以B分组 求出
  • git撤销一次代码提交方法

    以下方法亲测有效 但是根据需求选择哦 友情提示 注意备份 方法一 1 删除上一次提交 或者撤销上一次合并 reset方式是将HEAD指针指到指定提交 历史记录则不会出现你删除的上步commit记录等 合并时间线等都会删除彻底 并删除 mer
  • 分享是个好习惯

    无止境的求索 把脚印记下来 累了 迷茫了 回头望望 记住来时的路 收拾收拾行囊 云淡风轻
  • C++字符指针的特殊

    如果我们对一个非字符的指针进行操作 方法是这样的 注意 int p 则p i 等价于 p i 定义 1 int a 7 int p a 或者 2 int a 7 int p p a 或者 3 int a 7 int p p a 1 这样定义