你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

c++中的字符串

[复制链接]
gaosmile 发布时间:2020-4-14 11:13
-----对于c语言当中,你好像没有看到有关于字符串定义的关键字,不像我们常规的整型、浮点型、字符类型、指针、数组、结构体等数据类型,都能够一眼就能看出他们是什么数据类型,但是如果你对c语言理解不是很深的话,那你可能就不能"享受"到这里面的"美味"用法了,既然标题都标注了这个,我也不卖关子,下面会有总结分享的。说完了c,那么对于我们的c++来说,它定义字符串就简单多了,因为有关键字来定义,你一看就知道。那么下面大家就随着我的笔步一起来看看究竟吧!


一、c++中的字符串表示形式:
  • 有可能有些网友还没怎么接触到c++(c++它是一门面向对象的语言,而c是一门面向过程的语言,所以这里可能没接触过那个面向对象的网友不习惯这个用法,不过还是建议至少要掌握一门面向对象的语言,在这个发展快速的时代,不能太固步自封了(我这里也是简单的介绍一下c++中的字符串,不会设计到类和对象什么的,只是和c语言做个对比)。)

1、什么是字符串?
        
       (1)字符串就是一串字符。字符反映在现实中就是文字、符号、数字等人用来表达的字符,反映在编程中字符就是字符类型的变量。C++和C语言中都使用ASCII编码对字符进行编程,编码后可以用char型变量来表示一个字符。字符串就是多个字符打包在一起共同组成的。

         (2)字符串在内存中其实就是多个字节连续分布构成的(类似于数组,字符串和字符数组非常像)。

         (3)不管是C++还是C语言中字符串都有3个核心要点:第一是用一个指针指向字符串头;第二是固定尾部(字符串总是以'\0'来结尾);第三是组成字符串的各字符彼此地址相连。
        (4)'\0'是一个ASCII字符,其实就是编码为0的那个字符(真正的0,和数字0是不同的,数字0有它自己的ASCII编码)。要注意区分'\0'和'0'和0。(0等于'\0','0'等于48)

微信图片_20200414110944.jpg


2、c++中的字符串表示:
      在c++中我们要定义一个字符串的话,我们使用string来定义:1string str="linux";



二、c语言里面的字符串如何来使用呢?
  • 在我们C语言里面没有String类型的,但是C语言中的字符串是可以通过字符指针来间接实现的,下面来看详细解析。
1、C语言中定义字符串实现:         
        我们先来用字符指针的形式来定义一个字符串效果:1 char *p = "linux";
此时p就叫做字符串,但是实际上p只是一个字符指针(本质上就是一个指针变量,只是p指向了一个字符串的起始地址而已)。
  • 注意:         char *p = "linux";在这段代码中,p本质上是一个字符指针,占4字节;"linux"分配在代码段,占6个字节(不要忘了加"\0");实际上总共耗费了10个字节,这10个字节中:4字节的指针p叫做字符串指针(用来指向字符串的,理解为字符串的引子,但是它本身不是字符串),5字节的用来存linux这5个字符的内存才是真正的字符串,最后一个用来存'\0'的内存是字符串结尾标志(本质上也不属于字符串)。
    微信图片_20200414110948.png


2、字符串和字符数组:
  • 当然除了上面那种表示法,我们经常会在c语言当中用一维数组来存储字符串的。下面就用实际代码来讲解它的具体表示:


    1#include <stdio.h>
    2int main(void)
    3{
    4char *p = "linux";          // 字符串
    5char a[] = "linux";         // 字符数组
    6
    7printf("p = %s.\n", p);
    8printf("a = %s.\n", a);
    9
    10return 0;
    11 }



微信图片_20200414110951.png

1、字符数组初始化与sizeof、strlen:

     (1)sizeof是C语言的一个关键字,也是C语言的一个运算符(sizeof使用时是sizeof(类型或变量名),所以很多人误以为sizeof是函数,其实不是),sizeof运算符用来返回一个类型或者是变量所占用的内存字节数。为什么需要sizeof?主要原因一是int、double等原生类型占几个字节和平台有关;二是C语言中除了ADT之外还有UDT(用户数据类型,比如还是rtos实时操作系统中,经常会看到使用typedef来重新给基本数据类型来定义一个自己写代码的名称,这也主要是考虑跨平台因素,因为不同平台的常规数据类型大小所占用的字节大小是不一样,所以在换了一个平台下,我们就可以不用全部更改大小,只需改这个别名就行),这些用户自定义类型占几个字节无法一眼看出,所以用sizeof运算符来让编译器帮忙计算。

(2)strlen是一个C语言库函数,这个库函数的原型是:size_t strlen(const char *s);这个函数接收一个字符串的指针,返回这个字符串的长度(以字节为单位)。注意一点是:strlen返回的字符串长度是不包含字符串结尾的'\0'的。我们为什么需要strlen库函数?因为从字符串的定义(指针指向头、固定结尾、中间依次相连)可以看出无法直接得到字符串的长度,需要用strlen函数来计算得到字符串的长度。

2、代码示例来演示sizeof和strlen:
1  #include <stdio.h>
2  #include <string.h>
3
4   int main(void)
5  {
6
7
8 /*    char *p = "linux";
9printf("sizeof(p) = %d.\n", sizeof(p));     // 8这个是计算指针所占内存字节大小,32的系统,指针占4个字节大小;64位的系统,指针占用8个字节大小
10printf("strlen(p) = %d.\n", strlen(p));     // 5   注意这里不要计算那个结尾的字符"\0"
11
12  */
   
13
14 /*    char a[7] = "windows";          // a[0] =
15 'w', a[1] = 'i', ````a[6] = 's'
16printf("sizeof(a) = %d.\n", sizeof(a));     // 7
17printf("strlen(a) = %d.\n", strlen(a));     // >=7   这里为啥是这样,主要是考虑到栈里面的数据可能是上次还有可能遗留下来
18  */
19
20   /
*
21char a[] = "windows";           // a[0] = 'w', a[1] = 'i', ````a[6] = 's', a[7] = '\0'
22printf("sizeof(a) = %d.\n", sizeof(a));     // 8
23printf("strlen(a) = %d.\n", strlen(a));     // 7
24   */   
25   /
*   
26char a[5] = "windows";
27printf("sizeof(a) = %d.\n", sizeof(a));     // 5
28printf("strlen(a) = %d.\n", strlen(a));     // 5
29   */
30
31  /
*
32char a[5] = "lin";
33printf("sizeof(a) = %d.\n", sizeof(a));     // 5  
34printf("strlen(a) = %d.\n", strlen(a));     // 3
35   */
36  /
*
37char a[5] = {2, 3};
38printf("sizeof(a) = %d.\n", sizeof(a));     // 5
39printf("strlen(a) = %d.\n", strlen(a));     // 2
40  */   
41 /
*
42char a[5] = {0};
43printf("sizeof(a) = %d.\n", sizeof(a));     // 5
44printf("strlen(a) = %d.\n", strlen(a));     // 0
45   */
46  /
*   
47char a[5];
48printf("sizeof(a) = %d.\n", sizeof(a));     // 5
49printf("strlen(a) = %d.\n", strlen(a));     // 5
50  */   
51
52  /
*
53char *p = "linux";
54//int len = strlen(p);
55int len = mystrlen(p);
56printf("len = %d.\n", len);
57 */   
58return 0;
59 }
60


说明:
      
            (1)上面我没有演示输出结果,我在代码后面有注释,后面没注释的地方,分析方法是一样的,自己也可以尝试的分析为啥是这样子。
        
              (2)sizeof(数组名)得到的永远是数组的元素个数(也就是数组的大小),和数组中有无初始化,初始化多、少等是没有关系的;strlen是用来计算字符串的长度的,只能传递合法的字符串进去才有意义,如果随便传递一个字符指针,但是这个字符指针并不是字符串是没有意义的。

              (3)当我们定义数组时如果没有明确给出数组大小,则必须同时给出初始化式,编译器会根据初始化式去自动计算数组的大小(数组定义时必须给出大小,要么直接给,要么给初始化式)。


3、字符数组与字符串的本质差异(内存分配角度):         (1)字符数组char a[] = "linux";来说,定义了一个数组a,数组a占6字节,右值"linux"本身只存在于编译器中,编译器将它用来初始化字符数组a后丢弃掉(也就是说内存中是没有"linux"这个字符串的);这句就相当于是:char a[] = {'l', 'i', 'n', 'u', 'x', '\0'};

   (2)字符串char *p = "linux";定义了一个字符指针p,p占4字节,分配在栈上;同时还定义了一个字符串"linux",分配在代码段;然后把代码段中的字符串(一共占6字节)的首地址(也就是'l'的地址)赋值给p。

   (3)总结对比:字符数组和字符串有本质差别。字符数组本身是数组,数组自身自带内存空间,可以用来存东西(所以数组类似于容器);而字符串本身是指针,本身永远只占4字节,而且这4个字节还不能用来存有效数据,所以只能把有效数据存到别的地方,然后把地址存在p中。也就是说字符数组自己存那些字符;字符串一定需要额外的内存来存那些字符,字符串本身只存真正的那些字符所在的内存空间的首地址。
收藏 评论0 发布时间:2020-4-14 11:13

举报

0个回答

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版