C、C++ 对于char*和char[]的理解

2023-05-16

 1、char*和char[]的共同点

都是指针,指向第一个字符所在的地址

2、char*的用法

char a[] = "aaa";
char* p1 = a;  //char*是常量指针(常量的指针),刚好a就是个指针常量。
char* p2 = "ppp"; //不建议
const char* p2 = "ppp";//等效于 char const* p2 = "ppp";

char*是一个常量指针(常量的指针),即它指向的内存中的内容不能发生改变,但它可以改变自身的指向。

另外,不加const,直接将一个常量字符串赋值给char*是有隐患的(即char*p = "ppp"),它会做如下的操作:

1、在栈区开辟内存放char* p。

2、在文字常量区(即常量存储区)开辟内存放"ppp"。

3、将"ppp"中第一个字符的内存地址赋值给p。

崩溃隐患:当编译strcmp(p, "hello");时系统不会报错,因为符合第一个参数char*第二个参数const char*的参数限制。实际运行时,系统将试图修改文字常量区的内容,而文字常量区属于只读区,进而引发崩溃。若加上const就会避免它进入该类函数哈哈~

如果一定要改变值,应该写char* p  = "ccc";改变p在文字常量区的指向。

 3、char[]的用法

//char[]
char a[20] = "aaa";
char b[] = "bbbbb";
char c[] = {'s','t','r','i','n','g','\0'};
char d[] = {"dddd"};

//一般这样初始化
char num[20] = {0};
//初始化的目的是为了添加\0,否则\0会跑到莫名其妙的地方导致很多错误。
//ASCII码中0对应的是nul符,即\0。这一行的意义就是给0~19都赋\0。

第一行中,"aaa"中的每一个字符分别赋值给数组中的每一个元素并存储在栈上,数组位置不够的字符以"\0"填充,且a[19]一定是"\0"。 

另外,由于char[]是一个指针常量,它等同于char *const a(但这玩意儿不能用于读入,暂时理解是没有指定长度),因此指针中所保存的地址不能发生变化,下面的写法就是错误的。

char a[] = "aaa";
a = "hello"; // "hello"会在文字常量区开辟一片新内存

应该改变地址内保存的值

a[0] = 'b';

4、怎么输出char*地址

虽然指针名就代表的是地址,但在输出时需要加&,仅限cout。

C++:

const char* p = "ppp"; 
cout<<&p<<endl; //地址 方法一
cout<<(void*)p<<endl;//地址 方法二
cout<<p<<endl; //ppp

C:

const char* a = "ppp";
printf("%p \n", a); //16进制地址,不过 %p的输出格式并不统一,有的编译器带0x前缀,有的不带
printf("%#X \n", a);//16进制地址,前缀统一是0x
printf("%s \n", a);  //ppp

5、strlen和sizeof

sizeofstrlen
性质运算符函数
功能以字节为单位计算操作数占用的内存大小计算字符串的长度(strlen函数遇到\0就会停止下来,返回\0前出现的字符个数,不包括\0)
时间编译时运行时
参数类型/各种objectconst char*\char*\char[]
返回值size_tsize_t
头文件运算符没有头文件string.h

ps:

(1)它们返回的都是size_t,这是一种记录操作数大小的数据类型,属于无符号长整型,因此不要用减法比较返回值,因为结果始终是无符号长整型(非负数)。

(2)sizeof常用参数一览

struct test{
    int num;
}
int a;
sizeof(int);
sizeof(a);
sizeof(test);//sizeof(struct test);
sizeof(fun());//该函数必须有返回值

(3)sizeof的主要功能是参与存储分配,例如:

void* malloc(size_t size);
size_t fread(void* ptr, size_t size, size_t nmemb, FILE* stream);
void* memset(void* s, int c, sizeof(s));

6、char*和string

区别stringchar*
本质STL中的一个容器,string封装了char*。指针
内存管理由系统管理,除非系统内存池用完,否则不会出现内存问题栈/堆,如果是堆需要手动释放

string和const char*互转

//string转const char*
#include <string>
string s = "sss";
const char* c = s.c_str();

//const char*转string
const char* c = "ppp";
string s = c;

string和char*互转

//string转char*
#include <string>
string str = "string";
//法一
char* chr = const_cast<char*>(str.c_str());
//法二
char *cstr = &str[0];


//char*转string
char* c = "ppp";
string s = c;

7、赋NULL时究竟在做什么

C++:

/* Define NULL pointer value */
#ifndef NULL
    #ifdef __cplusplus
        #define NULL    0
    #else  /* __cplusplus */
        #define NULL    ((void *)0)
    #endif  /* __cplusplus */
#endif  /* NULL */

C:

#define NULL    ((void *)0)

小结

1、const在*前修饰指定的类型,const在*之后修饰指针。

2、 读入只能是char [],因为读入需要明确的地址,注意必须标定长度。

        改值还得是char*,因为方便。

//一般读入
char num[20];//必须标定长度
cin>>num;
scanf("%s", num);

//还可以这样读入
char num[20];//必须标定长度
char* p = num;
cin>>p;

3、char[]在运行时刻赋值,char*在编译时刻赋值

参考文章:

char * 与char []区别总结_bitcarmanlee的博客-CSDN博客_char和char*的区别1.先上结论c++代码里头经常见到char * 与char []的写法,这两种写法都可以表示一个字符串。比如:void charcode() { char* a = "c1"; char b[] = "c2"; printf("a=%s, b=%s", a, b);}上面这段代码,最后输出的结果为a=c1, b=c2所以这两种方式都可以表示字符串,那么区别到底是什么?我们先说结论,后面再来分析:char * 这种方式表示常量指针,char[] 这种表示指针常量!2https://blog.csdn.net/bitcarmanlee/article/details/124166842char数组的地址怎么输出_JINGpuzzle的博客-CSDN博客_char数组的地址对于int这样的数据类型如int num[3];cout<<num<<endl;输出第一个元素的地址cout<<&num[1]<<endl;输出第二个元素的地址但是我们知道char字符串数组会比较特殊我们先来看这样一个例子按理说数组名不就应该是数组的第一个元素的地址吗,为什么他把整个字符串都给输出了?好,下面我们再来看一个例子因此我们可以得出这样的答案,cout在遇到char的指针时,会输出整个字符串,直..https://blog.csdn.net/Jing_JiaNan/article/details/121170349c++指针(一)——指针的定义以及写法_大豆木南的博客-CSDN博客_c++定义指针本系列讲述指针的文章一共分为六篇文章目录如下:一、c++中指针的定义以及写法二、定义变量时的内存分配三、指针与数组名的关系四、常量指针与常量指针五、指针的指针六、指针和引用好了,按照这个顺序开启探索c++指针之旅~一、c++中指针的定义int *p; //*号前有空格,可以是任意个空格int* p; //*号后有空格,可以是任意个空格int*p; //*号前后都没有空格int * p; //...https://blog.csdn.net/qq_32103261/article/details/80221014

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

C、C++ 对于char*和char[]的理解 的相关文章

  • 可以将整数值赋给 char,但不能将整型变量赋给 char

    为什么下面的代码不能编译 int n 5 char c n 但以下确实可以编译 char c 5 在这两种情况下我不是只是为 char 分配一个整数值吗 A char可以分配给一个int没有强制转换 因为这是一个扩大的转换 为了执行相反的操
  • 将 std::string 转换为 C 函数的 char* 时要注意什么?

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

    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
  • 将字母转换为数字[重复]

    这个问题在这里已经有答案了 我是 matlab 新手 我只是想将字母转换为数字 这样 A 1 B 2 C 3 我所有的数字都是大写的 当然 我可以为每个字符定义常量 但是有更短的方法吗 Thanks See the char功能 您可以给它
  • 如何更改 Rust 字符串中特定索引处的字符?

    我正在尝试更改字符串中特定索引处的单个字符 但我不知道如何更改 例如 我如何将 hello world 中的第四个字符更改为 x 以便它成为 helxo world 最简单的方法是使用replace range https doc rust
  • 为什么 char 数组必须以空字符结尾?

    为什么 chararray必须以空字符结尾 有什么理由我必须将空字符添加到每个char array 看来他们受到的待遇是一样的 char 数组不必以 null 终止 不依赖于此的标准库函数包括memcpy memmove strncpy 最
  • 我如何将 int 数组转换为字符串数组[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我有一个整数数组 int a 5 5 21 456 1 3 我需要将这些数字存储到char数组 这样 char 数组将具有如下内容 c
  • 打印一个字符*

    我提前为这个愚蠢的问题道歉 这是我的结构定义 struct vcard char cnet char email char fname char lname char tel 我正在尝试使用函数 vcard show vcard c 打印此
  • C问题:为什么char实际上占用了4个字节的内存?

    我写了一个小程序来检查 char 在内存中占用了多少字节 它显示 char 实际上在内存中占用了 4 个字节 我知道这主要是因为字对齐 并且没有看到 char 只有 1 个字节的优势 为什么不使用 4 个字节作为 char int main
  • 使用字符的 for 循环绘制具有特定颜色的多条线

    我想在一张图表上绘制 13 条线 每行代表我的数据的一个子集 按 盆地 列中的字符分组 我所拥有的有效 但我想使用 for 循环使其更有效 输出如下所示 https i stack imgur com gTapP png 可使用的简化数据框
  • 将 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 打
  • 运算符“==”不能应用于“char”和“string”类型的操作数

    我正在开发一个自我指导的简单程序来练习迄今为止学到的概念 我的项目与国际象棋相关 在本例中具体是棋盘 a h 列和 1 8 行 系统会询问用户特定棋子的当前位置 希望输入为列字母 后跟行数字 为了验证这一点 我首先检查该值是否作为两个字符的
  • 如何在 C 中将浮点数转换为 4 字节字符?

    我想将浮点数 例如 2 45 转换为 4 字节字符数组 所以 2 45 应该是这样的 FS 这是二进制的 IEEE 表示2 45 01000000 00011100 11001100 11001101 我已经解决了这个问题 但它的复杂性很差
  • 实现 `memcpy()`:需要 `unsigned char *`,还是只需要 `char *`?

    我正在实施一个版本memcpy 能够与它一起使用volatile 使用安全吗char 或者我需要unsigned char volatile void memcpy v volatile void dest const volatile v
  • Java中的字符算术

    在玩的过程中 我遇到了一些对我来说似乎很奇怪的事情 以下不是有效的 Java 代码 char x A x x 1 possible loss of precision 因为其中一个操作数是整数 所以另一个操作数被转换为整数 结果无法分配给字
  • 字符串文字在内存中的什么位置?堆栈/堆? [复制]

    这个问题在这里已经有答案了 可能的重复 C 字符串文字 它们去了哪里 https stackoverflow com questions 2589949 c string literals where do they go 据我所知 一般来
  • 在C#中,如何检测一个字符是否是非ASCII字符?

    我想在 C 中检查 char 是否包含非 ASCII 字符 检查特殊字符的最佳方法是什么 例如志 or ASCII 范围为 0 127 因此只需检查该范围 char c a or whatever char you have bool is
  • 如何在 Arduino 中将 char 变量作为数字打印到串行端口?

    我正在使用 Arduino Uno 我正在从 EEPROM 读取一个字节值并将该值存储在类型变量中char 1 字节 我想将变量的值作为数字 而不是相应的 ASCII 代码 打印到串行监视器 例如考虑char val 5 我想查看串行监视器
  • 删除字符串 C 的第一个字符

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

随机推荐

  • QT 笔记5 |Qt多线程(QThread)

    一 Qt多线程 QThread 1 创建线程方法1 xff1a QObject moveToThread class Myclass public QObject Q OBJECT public slots void func void 耗
  • QT 笔记6 | Qt网络编程

    回顾 xff1a 1 Qt多线程 QThread 1 xff09 创建线程 方法1 xff1a moveToThread 方法2 xff1a 继承QThread xff0c 重写run函数 2 xff09 线程同步 互斥锁 xff1a QM
  • QT 笔记7 | UDP编程

    回顾 xff1a 1 xff09 控件类 QT 43 61 widgets QApplication Qt的gui应用程序 QWidget 控件基类 QLabel 标签 QPushButton 按钮 QDialog 对话框 QMainWin
  • 学习c语言

    今天学习了if语句和 xff45 xff4c xff53 xff45 运用 xff43 语言更加顺手 xff0c 之前一些都能实施 xff0c 真是太开心了 include lt stdio h gt int main 初始化 int pr
  • 求符合给定条件的整数集(做题)

    题目如上 xff1b 首先我们先想思路 xff1a 先来一个输入 xff0c 读入这个数 xff0c 然后我们需要三个变量来储存这三个数 xff1b 然后我们遍历所有的组合 xff0c 这个依靠循环 接下来是代码 xff1a include
  • 水仙花数(做题)

    代码如下 xff1a include lt stdio h gt int main int a scanf 34 d 34 amp a float t t 61 0 1 while a gt 0 t 61 t 10 a 判断几位数 int
  • 一分钟了解动态内存分配

    谈到这 xff0c 必然离不开malloc函数 在上面可以看出此函数需要一个头文件 include lt stdilb h gt 而且返回类型是void 传进去的是空间大小 xff0c 此函数申请的空间是字节为单位的 这其中的就分配了100
  • 动态内存分配深究

    接下来我们将探究以下三个问题 xff1a 1 相邻两次malloc得到的空间是否是连续的呢 xff1f 2 你得到的空间的实际大小是否就是你要求的大小呢 xff1f 3 如果你malloc零长度会得到什么结果呢 xff1f 第一个问题 xf
  • 同一个页面不打开两次

    lt script language 61 34 javascript 34 gt function popwin3 path window open path 34 cart 34 34 height 61 520 width 61 52
  • 超易懂!二分查找 详析

    二分算法的 本质 是 xff1a 假如我们可以找到事物的 某种性质 xff0c 这种性质 可以将区间一分为二 xff0c 一半满足 xff0c 一半不满足 我们就可以二分 另外 xff0c 有 连续性 必可以 二分 二分模板一共有两个 xf
  • 手摸手 Spring Cloud Gateway + JWT 实现登录认证

    你好 xff0c 我是悟空 前言 上篇我已经讲解了 Spring Cloud 的原理和实战 xff0c 这次就要结合 JWT 来实现登录认证的功能了 本文已收录至 深入剖析 Spring Cloud 底层架构原理 xff0c 已更新 18
  • 百行代码实现VLC简易视频播放器【VLC环境配置过程+可执行源码注释完整】

    文章目录 什么是VLC x1f680 VLC 库的集成 VLC环境配置演示 win10系统 43 vs2017 43 win64 x1f34e VLC 库的基本使用 x1f382 视频播放器实现 自定义函数Unicode2Utf8讲解 x1
  • HttpWebRequest 使用NetworkCredential 进行域认证下载时不成功 的解决方案

    最近在项目中使用pWebRequest 使用NetworkCredential 进行域认证下载时老不成功 xff0c 最后Google了解决方案 xff0c 发现几乎所有讨论的方案都不成功 xff0c 只好埋头自己解决 xff0c 最后总算
  • Firefox 的用户脚本管理器 greasemonkey 的使用一例

    一 什么是greasemonkey Firefox 的用户脚本管理器 greasemonkey 使你可以向任何网页添加DHTML语句 用户脚本 来改变它们的显示方式 就像CSS可以让你接管网页的样式 xff0c 而用户脚本 User Scr
  • Apache Http 服务器安装教程

    我在学习网络开发的时候需要从服务器上获得json数据 xff0c 所以在自己的电脑上安装了一个本地服务器 xff0c 其中遇到的一些问题 xff0c 在这里都写出来 首先 xff0c 我们需要访问apache http服务器的下载网页 xf
  • STM32的UART奇偶校验注意

    STM32的UART奇偶校验注意 STM32的UART在初始化时 xff0c 我们通常用到最多的就是无校验位 xff0c 1停止位 但是我在项目中也遇到某些芯片通信用的需要奇校验或者偶校验 xff0c 这里需要特别注意的是STM32中开启奇
  • Realtek RTL8762C/Realtek RTL8762D学习记录

    本人基于日常工作整理编写的8762C FAQ文档 xff0c 记录RTL8762C 8762D系列软件开发常见问题以及解决方案 希望它能发挥更多作用 帮到有需要的朋友 关键字 xff1a 8762CMF 8762CK 8762CJ 8762
  • 蓝牙BLE---DA14683的SPI主机通信讲解

    DA14683的SPI主机通信例程 Date 2018 12 19 Create Jim 导入例程 首先导入ble peripheral例程或者pxp reporter例程 再到以下位置打开硬件SPI的宏定义 xff1a 获取SPI例程源码
  • 06.5 Code

    06 5 Code 推力 force 推力的应用旋翼的气动阻力空气阻力矩滚转力矩电机的转速 推力 force span class token comment force 61 电机的转速 xff5c 电机的转速 xff5c xff08 带
  • C、C++ 对于char*和char[]的理解

    1 char 和char 的共同点 都是指针 xff0c 指向第一个字符所在的地址 2 char 的用法 char a 61 34 aaa 34 char p1 61 a char 是常量指针 xff08 常量的指针 xff09 xff0c