char* char[]

2023-05-16

C++判断char*的指向

char *a = "Peter";
char b[] = "Peter";
char *c = new char[6];
strcpy_s(c, 6, "Peter");

这里a指向常量区

b指向栈区

c指向堆区

 

//main.cpp
int a=0;    //全局初始化区
char *p1;   //全局未初始化区
main()
{
   int b;栈
   char s[]="abc";   //栈
   char *p2;         //栈
   char *p3="123456";   //123456\0在常量区,p3在栈上。
   static int c=0;   //全局(静态)初始化区
   p1 = (char*)malloc(10);
   p2 = (char*)malloc(20);   //分配得来得10和20字节的区域就在堆区。
   strcpy(p1,"123456");   //123456\0放在常量区,编译器可能会将它与p3所向"123456"优化成一个

地方。
}

相同点

首先 这两种类型都可以对应一个字符串,比如: 
char * a=”string1”; 
char b[]=”string2”; 
printf(“a=%s, b=%s”, a, b); 
其中a是一个指向char变量的指针,b则是一个char数组(字符数组),

其次 ,很多时候二者可以混用,像函数传参数的时候,实参可以是char*,形参可以是 char[],比如: 
void fun1(char b[]){ 
printf(“%s”,b); 

int main(){ 
char *a=“HellowWorld”; 
fun1(a); 

反过来,实参可以是char[],形参可以是 char *也是可以的。 
存在即合理,char *和char[]肯定是有本质的不同。

不同点

1.char*是变量,值可以改变, char[]是常量,值不能改变。 
比如: 
char * a=”string1”; 
char b[]=”string2”; 
a=b; //OK 
a=”string3”; //OK 
b=a; //报错!左边操作数只读 
b=”string3” //报错!左边操作数只读

解释: a是一个char型指针变量,其值(指向)可以改变; 
b是一个char型数组的名字,也是该数组首元素的地址,是常量,其值不可以改变 。

2.char[]对应的内存区域总是可写,char*指向的区域有时可写,有时只读 
比如: 
char * a=”string1”; 
char b[]=”string2”; 
gets(a); //试图将读入的字符串保存到a指向的区域,运行崩溃! 
gets(b) //OK 
解释: a指向的是一个字符串常量,即指向的内存区域只读; 
b始终指向他所代表的数组在内存中的位置,始终可写! 
注意,若改成这样gets(a)就合法了: 
char * a=”string1”; 
char b[]=”string2”; 
a=b; //a,b指向同一个区域,注意这里改变了a的指向 
gets(a) //OK 
printf(“%s”,b) //会出现gets(a)时输入的结果 
解释: a的值变成了是字符数组首地址,即&b[0],该地址指向的区域是char *或者说 char[8],习惯上称该类型为字符数组,其实也可以称之为“字符串变量”,区域可读可写。

注意:char *本身是一个字符指针变量,但是它既可以指向字符串常量,又可以指向字符串变量,指向的类型决定了对应的字符串能不能改变。

3.char * 和char[]的初始化操作有着根本区别:

测试代码: char *a=”Hello World”; 
char b[]=”Hello World”; 
printf(“%s, %d\n”,”Hello World”, “Hello World”); 
printf(“%s, %d %d\n”, a, a, &a); 
printf(“%s, %d %d\n”, b, b, &b); 
结果:

这里写图片描述

结果可见:尽管都对应了相同的字符串,但”Hellow World”的地址 和 a对应的地址相同,与b指向的地址有较大差异;&a 、&b都是在同一内存区域,且&b==b 
根据c内存区域划分知识,我们知道,局部变量都创建在栈区,而常量都创建在文字常量区,显然,a、b都是栈区的变量,但是a指向了常量(字符串常量),b则指向了变量(字符数组),指向了自己(&b==b==&b[0])。

说明以下问题:

char * a=”string1”;是实现了3个操作: 
1声明一个char*变量(也就是声明了一个指向char的指针变量)。 
2在内存中的文字常量区中开辟了一个空间存储字符串常量”string1”。 
3返回这个区域的地址,作为值,赋给这个字符指针变量a 
最终的结果:指针变量a指向了这一个字符串常量“string1” 
(注意,如果这时候我们再执行:char * c=”string1”;则,c==a,实际上,只会执行上述步骤的1和3,因为这个常量已经在内存中创建)

char b[]=”string2”;则是实现了2个操作: 
1声明一个char 的数组, 
2为该数组“赋值”,即将”string2”的每一个字符分别赋值给数组的每一个元素,存储在栈上。 
最终的结果:“数组的值”(注意不是b的值)等于”string2”,而不是b指向一个字符串常量

PS: 
实际上, char * a=”string1”; 的写法是不规范的! 
因为a指向了即字符常量,一旦strcpy(a,”string2”)就糟糕了,试图向只读的内存区域写入,程序会崩溃的!尽管VS下的编译器不会警告,但如果你使用了语法严谨的Linux下的C编译器GCC,或者在windows下使用MinGW编译器就会得到警告。

所以,我们还是应当按照”类型相同赋值”的原则来写代码: const char * a=”string1”; 
保证意外赋值语句不会通过编译。

小结

对于 
const char * a=”string1” 
char b[]=”string2”;

1.a是const char 类型, b是char const类型 
( 或者理解为 (const char)xx 和 char (const xx) )

2.a是一个指针变量,a的值(指向)是可以改变的,但a只能指向(字符串)常量,指向的区域的内容不可改变;

3.b是一个指针常量,b的值(指向)不能变;但b指向的目标(数组b在内存中的区域)的内容是可变的

4.作为函数的声明的参数的时候,char []是被当做char *来处理的!两种形参声明写法完全等效!

 

 

char *p="hello“; 
*(p+2)='w'; 
这里的p是一个指向常量字符串的指针
他可以相当与:const char *p="hello"

根据定义:指向常量字符串的指针不能更改指针指向的内容,但是可以改变本身的值,既是执行*(p+2)='w'; (错误) p="bcvcbvv"(正确)

char pp[] = "hello";

这个相当与指针常量,就是本身是个常量<因为pp就是数组的一个引用,引用本身就是指针常量>
相当与 char const *pp="hello";  

根据定义:指针常量不能改变本声的值,但是可以改变指向的值

既是 *(pp+2)='W'(准确) pp="mnbmbmb"(错误)

 

 

 

 

 

(1) char* ptr="Hello World!";(新标准c++中这样写会有警告:ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings] )

(2) char str[]="Hello World!";

"Hello World!"本身都在存储在常量储存区。

但是 char *str = "Hello World!";

会在堆栈上储存一个4个字节(假定32位系统)的指针指向储存"Hello World!"的区域。

而 char str[] = "Hello World!";
会首先在堆栈上先分配一个13字节的char数组,然后把常量储存区的那个"Hello World!"复制过来。
--------------------- 
作者:叫毛哥 
来源:CSDN 
原文:https://blog.csdn.net/qq_38323666/article/details/81030972 
版权声明:本文为博主原创文章,转载请附上博文链接!

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

char* char[] 的相关文章

  • Java中的char和Character有什么区别?

    我需要知道Java中的char和Character有什么区别 因为当我编写java程序时 char可以工作 而Character却不起作用 char 是表示单个 16 位 Unicode 字符的原始类型 而 Character 是一个包装类
  • 将 std::string 转换为 C 函数的 char* 时要注意什么?

    我读过很多帖子询问如何转换 C std string or const std string to a char 将其传递给 C 函数 似乎在执行此操作时有很多警告 人们必须注意字符串是否连续以及许多其他事情 关键是我从来没有真正理解人们需
  • 在 C++ 中将整数存储到 char* 中

    我正在编写一些返回整数的代码 然后需要使用 ncurses 库中的 printw 输出该整数 但是 由于 printw 只接受 char 我不知道如何输出它 本质上 有没有办法将整数存储到 char 数组中 或者使用 printw 输出整数
  • 字符数组的初始值设定项字符串太长 C

    我正在开发一个程序 它接受输入并输出与输入相对应的数值 我在 char 部分收到错误 我不明白为什么当数组中只有 27 个字符且大小为 27 时会出现这样的错误 int main char greek 27 ABGDE ZYHIKLMNXO
  • 如何将此代码转换为使用字符串

    char recursivecombo char str int choices int level int len strlen str level if level choices for int i 0 i lt len 2 i pr
  • 从 ostream 获取 char* 而不进行复制

    我有一个ostream并且数据已写入其中 现在我想要该数据的形式char大批 有没有办法在不复制所有字节的情况下获取字符缓冲区及其大小 我的意思是 我知道我可以使用ostringstream并打电话str c str 但会产生一个临时副本
  • С++ 中的字符串文字是在静态内存中创建的吗?

    C 中的字符串文字是否在静态内存中创建并仅在程序退出时销毁 是的 字符串文字在程序的整个持续时间内都有效 即使在静态对象销毁期间也是如此 标准中的2 13 4 1说 普通字符串文字具有 n const char 数组 类型和静态存储持续时间
  • Ansichar 和 char 有什么区别? [复制]

    这个问题在这里已经有答案了 我最近遇到了这种数据类型不匹配的情况 这是我以前从未见过的 我希望有人能解释它们是什么以及它们有何不同 我得到的错误是 F2063 DCC 错误 E2010 不兼容的类型 AnsiChar 和 Char 历史上在
  • 指向常量字符的指针

    下面的代码指向a中的第一个字符字符数组可在只读存储器中使用 是对的吗 const char ptr String one 现在 当ptr开始指向另一个内存位置 ptr String two 第一个会发生什么字符数组 执行结束时该内存位置是否
  • 为什么“char **”类型的索引给出整个字符串?

    考虑这个片段 include
  • 将 C dll 代码编组为 C#

    我在 dll 中有以下 C 代码签名 extern declspec dllexport unsigned char funct name int w int h char enc int len unsigned char text in
  • char * 变量地址与 char[] 变量地址

    我从以下两个声明和初始化中打印出地址和字符串 char strPtr char This is a string made on the fly char charArray Chars in a char array variable 打
  • 使用 int 值初始化向量

    我想用这个 ASCII 代码初始化这个 char 向量 vector
  • C 中的十六进制到字符数组

    Given a string of hex values i e e g 0011223344 so that s 0x00 0x11 etc 如何将这些值添加到 char 数组 相当于说 char array 4 0x00 0x11 您无
  • 强制 telnet 客户端进入字符模式

    我有一个应用程序 我接受来自 telnet 客户端的套接字连接 并建立一个简单的键盘驱动的字符 GUI telnet 客户端 至少在 Linux 上 默认为一次一行模式 所以我总是必须这样做 mode char手动 浏览相关 RFC 表明
  • ColdFusion:无效的 XML 控制字符(十六进制)

    我正在尝试使用创建一个 xml 对象
  • 删除字符串 C 的第一个字符

    我试图删除字符串的第一个字符并保留其余部分 我当前的代码无法编译 我对如何修复它感到困惑 My code char newStr char charBuffer int len strlen charBuffer int i 1 char
  • 如何将单个 char 转换为 int [重复]

    这个问题在这里已经有答案了 我有一串数字 例如 123456789 我需要提取它们中的每一个以在计算中使用它们 我当然可以通过索引访问每个字符 但是如何将其转换为 int 我研究过 atoi 但它需要一个字符串作为参数 因此 我必须将每个字
  • JNI 将 Char* 2D 数组传递给 JAVA 代码

    我想从 C 代码通过 JNI 层传递以下指针数组 char result MAXTEST MAXRESPONSE 12 12 8 3 29 70 5 2 42 42 在java代码中我写了以下声明 public static native
  • 如果存储字符串的 char 数组小于字符串,C++ 真正将字符串存储在哪里?

    我正在测试 C Premiere 书中有关 C 字符串的示例 const int size 9 char name1 size char name2 size C owboy 8 characters here cout lt lt How

随机推荐

  • 室内外融合北斗+uwb终端数据监听和发送控制方法

    UDP接收GNGGA报文同时转发UDP报文的方法 span class token keyword package span span class token class name Frame span span class token p
  • Ubuntu使用终端命令安装谷歌Chrome浏览器

    使用命令行安装谷歌浏览器稳定版 span class token function sudo span span class token function wget span http www linuxidc com files repo
  • 无人机PX4使用动捕系统mocap的位置实现控制+MAVROS

    动捕系统Optitrack xff0c 有很高的定位精度 xff0c 能够给无人机提供比较精确的位置信息 xff0c 因此如果实验室有条件 xff0c 都可以买一套动捕系统 动捕系统的原理 xff1a 光学式动作捕捉依靠一整套精密而复杂的光
  • Optitrack使用ros完成实时接收刚体的位置与四元数信息

    1 Opitrack系统标定 工作环境 xff1a 运行Motive的Windows主机 和一台安装有ROS的ubuntu电脑 标定步骤 1 准备 优化捕获设置 xff1b 2 在相机预览窗口 xff08 Camera Preview xf
  • RoboMaster机甲大师比赛入门?我们从STM32开始!

    同步博客地址 xff1a 从STM32开始的RoboMaster生活 xff1a 入门篇 项目 amp 教程仓库 xff1a STM32 RoboMaster 1 0 STM32是什么 1 1 定义 ST 43 M 43 32 61 STM
  • C++头文件定义类的方法

    新手在写C 43 43 程序定义类的时候 xff0c 可能会犯一个错误 xff0c 就是在main函数文件里定义很多类 xff0c 一个文件中包含很多函数 xff0c 这样程序看起来很冗杂 今天总结一下如何在C 43 43 中使用头文件来定
  • 相机光学(十五)——如何提高相机标定的精度

    为了提高单目相机标定的精度 xff0c 认真看了张正友标定法的原文 xff0c 并且学习过网上一些牛人的方法 xff0c 但是大部分时候说的很笼统 xff0c 自己把这些经验总结起来并都测试了一下 xff0c 感觉靠谱的结论列出如下 xff
  • TCP/UDP、封装与解封装

    目录 传输类型 网络里面三层架构 TCP IP模型 OSI模型 TCP IP模型 掌握 TCP IP模型当中重点 数据传递过程中的封装和解封装 封装 解封装 TCP UDP ICMP ICMP错误报告 ICMP重定向 典型应用 PING应用
  • 解决 ERROR: cannot launch node of type [xxx]: can‘t locate node [xxx] in package [xxx]

    背景 xff1a 从github下载的ros代码 xff0c 修改添加节点后 xff0c catkin make 编译通过 xff0c 但在运行launch文件时候报错 原因 xff1a 1 从github上下载的很多文件 xff0c 下载
  • stm32控制步进电机

    本文使用DM542c驱动器驱动 使用前注意根据实际情况调节拨码开关 本文不会提到GPIO使能 xff0c 请自行使能 一 PWM操作驱动器使步进电机一直转 使能定时器时钟 xff0c 并配置基本参数 下图以TIM3为例 配置输出比较PWM1
  • 树莓派GPIO

    命令行执行下行 xff0c 即可得树莓派管脚编码表 gpio readall 也可看下图 xff1a BOARD 编号参考 Raspberry Pi 主板上 P1 接线柱的针脚编号 使用该方式的优点是无需考虑主板的修订版本 xff0c 无需
  • python opencv滤波

    1 均值滤波 算法简单 xff0c 计算速度快 xff0c 在去噪的同时去除了很多细节部分 xff0c 将图像变得模糊 cv2 blur 2 高斯滤波 去除高斯噪声 cv2 GaussianBlur 3 中值滤波 去除椒盐噪声 cv2 me
  • opencv imwrite()保存指定路径

    cpp为例 include lt opencv2 opencv hpp gt include lt string gt include lt iostream gt using namespace cv using namespace st
  • python pip安装的包的路径

    以ubuntu为例 从一个店家那里拿到的一个ubuntu环境中 xff0c 同时安装了python3 6和python2 7 xff0c 又安装了ros xff0c 最后pip安装包的位置很混乱 xff0c 安装的包不知道安装在了哪里 使用
  • solidworks实体显示线框

    sw有段时间没使用 xff0c 今天打开突然发现打开的sw窗口数超过1 xff0c 那么从第二个窗口以后的模型都显示成以下样子 xff08 无论是之前的文件还是新建的都不行 xff09 如上是一个圆盘 xff0c 明明是实体 xff0c 却
  • vscode使用虚拟环境

    我的conda没有添加入path xff0c 每次打开总是报错 一 选择对应虚拟环境的解释器 1 点击vscode的右下角这里 2 点击后可能会在vscode上方出现下图样子 xff0c 如果出现下图 xff0c 则点击第二项Select
  • TabError: inconsistent use of tabs and spaces in indentation

    错误原因是tab制表符和空格混用了 从其他地方复制源码容易出现此错误 解决办法 xff1a 把处于同级缩进的所有缩进修改统一 比较流行的几个编辑器都能标识tab和空格 xff0c 比如我用的vscode 用鼠标框选 不知道是tab还是空格的
  • 关于深度学习的问题笔记

    感谢沐神教我深度学习 x1f64f 损失为什么要平均 xff1f 平均即除以batch size xff0c 若不除 xff0c 则批越大梯度越大 xff0c 梯度下降的步长就越大 除以batch size可使梯度与批大小无关 也可以不在损
  • 简单(炫酷)的单链表快速排序写法

    昨天在复习快排的时候 在B站看到一个小哥哥说某大厂的面试让写一个单链表的快速排序 我们见的最多的快排写法都是从两端向中间扫描 这种写法在单链表上不能实现 哥们分析道 快排的核心思想是每次扫描后 所有pivot左侧的元素都比pivot小 右侧
  • char* char[]

    C 43 43 判断char 的指向 char a 61 34 Peter 34 char b 61 34 Peter 34 char c 61 new char 6 strcpy s c 6 34 Peter 34 这里a指向常量区 b指