说明:在C语言中字符串和字符数组有很多相似之处,却又有着一些不同。本文将针对其区别与联系,进行分析总结。

一.字符串

1.在C语言中,字符串是由双引号括起来的任意字符序列,如:“china”,”america”等。

2.很显然,一个字符占一个字节,那么 “china” 应该占5个字节,但这样想就错了。其实在上篇文章中提到过了,在生成一个由双引号引起的字符串时,系统会自动在其后面追加一个 ‘\0’ ,这个杠0是相当重要的,可以说是字符串的重要依据,它是字符串的结束标志。字符串的很多处理函数,如上篇文章提到的,都是依据这个杠0工作的。所以在这里如果打印 “china” 的大小,应该是 6 。需要注意的是,空串 “” 的大小是1,可以理解为只有一个 ‘\0’ 。

  1     printf("%d\n",sizeof("china"));
  2     printf("%d\n",sizeof(""));
  3     //打印结果为6、1

3.C 语言将常量字符串处理为一个指向数据段中一段字符串的字符指针或字符数组。我们可以将它付给一个 char * 的指针或 char型的数组。

  1     char *p= "abcdef";
  2     //C++中类型检查严格,将const char *赋给 char* 会有警告
  3     char arr[6] = "abcde";

4.字符串,准确说是字符串常量,因为其是不可以修改的。普通变量通常存储在代码段,而字符串常量则存储在数据段的只读数据段 (RO段) ,这也意味着字符串常量是不可修改的。如运行以下代码,程序将挂掉。

  1     char *p= "abcdef";
  2     p[1] = '0';

二.字符串和字符数组

数组前面已经说过了,字符数组也是其中的一种,只不过数组中的每个元素为字符型的。这里就直接说字符串与字符数组的关系。

1.相同之处:下面将以一段代码加以说明

  1     char *p= "abcde";
  2     char arr[] = "abcde";
  3     char *pp = p;
  4     int i = 0;
  5     printf("%s\n",p);
  6     printf("%s\n",arr);
  7     //打印字符串和字符数组
  8
  9     printf("%d ",sizeof("abcde"));
 10     printf("%d\n",sizeof(arr));
 11     //打印字符串和字符数组的大小
 12
 13     while(*pp)
 14         printf("%c ",*pp++);
 15     while(arr[i] != 0)
 16         printf("%c ",arr[i++]);
 17     //分别单独访问各自的元素

程序运行结果:

  1 abcde
  2 abcde
  3 6 6
  4 a b c d e a b c d e

由上述结果可知,在某种情况下(下文将说明),字符串和字符数组是等价的,尤其是程序最后几行,通过单独打印字符串和字符数组的每个元素,更是可以得知两者末尾都有一个 ‘\0’ 存在。那么,在什么情况下二者不等呢?

2.不同之处

(1.)前面已经说过了,字符串是一个常量,不可修改,但字符数组却不是这样的。你可以完全通过下标法对任意一个元素进行修改。

  1     char arr[] = "abcde";
  2     arr[0] = '1';
  3     arr[3] = '5';
  4     printf("%s",arr);

(2.)二者等价条件,及前面提到的某种情况

一个没有 ‘\0’ 作为结尾标识符的字符串不叫字符串,而字符数组中元素的存储并不会像字符串那样自动追加 ‘\0’ ,因此,字符数组和字符串等价的条件便是 ‘\0’ 的拷贝问题。一个正常的字符串,其末尾必定以  ‘\0’ 结尾,如 “china” ,虽然杠0 并没有显示出来,但我们应该明确的知道其末尾有一个杠 0 的存在,这点,在前面通过打印字符串的大小也可以证明。因此,在初始化字符数组的时候,其大小应该总是大于等于字符串的大小,这样以便于将字符串末尾的 ‘\0’拷贝到数组。如以下代码,其中 n 应该大于等于 sizeof(“abcde”) = 6。

  1 char arr[n] = "abcde";

(3.)越界情况

当数组的大小小于字符串的大小时,由于 ‘\0’没拷贝到数组中,因此,对数组的打印可能会发生越界行为,产生不确定结果。

  1     char arr[5] = "abcde";
  2     printf("%s",arr);

在笔者电脑上输出结果为:

  1 abcde?6

(4.)最优做法

利用数组可以省略大小的特点,依据数组的大小自适应。这样也会避免浪费空间。

  1     char arr[] = "china";
  2     printf("%s\n",arr);

三.字符数组的拓展

既然字符数组可以存储任意字符元素,那么万一字符数组在前面元素中就已经出现了 ‘\0’ 而非最后一个元素是 ‘\0’ 呢?

  1 #include<stdio.h>
  2 #include<string.h>
  3 int main()
  4 {
  5     unsigned int i = 0;
  6     char arr[] = "c0hi0n\0a ";
  7     printf("%s\n",arr);
  8     printf("%d\n",sizeof(arr));
  9     printf("%d\n",strlen(arr));
 10     for(;i<sizeof(arr);i++)
 11         printf("%x ",arr[i]);
 12     return 0;
 13 }

程序运行结果:

  1 c0hi0n
  2 10
  3 6
  4 63 30 68 69 30 6e 0 61 20 0

由以上测试可知,数组只是一个存储元素的构造类型,其中的元素可以是任意的,打印数组大小时,只会跟元素的多少以及元素的类型有关,与其中元素是不是杠 0 无关。而当用 strlen()来判断该数组的长度时,由于其判断标识为 ‘\0’ ,因此不能正确得到数组的实际长度,只能得到 ‘\0’前面元素的长度。而对整个数组以字符串的格式打印时,也是同样的道理。只有当对字符数组的元素挨个单独打印,才能见到其真貌。上述代码是以十六进制 ASCII 对数组元素进行打印的。需要注意的是:0 并不是 ‘\0’,应该加以区分。

转载于:https://www.cnblogs.com/tuihou/p/9835567.html

(C/C++学习)15.C语言字符串和字符数组相关推荐

  1. C语言字符串与字符数组

    C语言字符串与字符数组 1. 字符串与字符数组 1.1 C 语言字符串 什么是字符串? 通俗的讲字符串是由一串字符组成,例如 "Hello World\n",即是一个字符串. C ...

  2. C语言—字符串与字符数组,字符串数组与字符串指针的区别

    字符串与字符数组 字符串一定是一个char的数组,但char的数组未必是字符串.--以字符'\0'结尾的char数组就是一个字符串,但如果char数组没有以'\0'结尾,那么就不是一个字符串,只是普通 ...

  3. C语言字符串、字符数组

    代码及结果 #include <stdio.h>int main() {char *a = "hello";char b[] = "hello";p ...

  4. C语言——字符串和字符数组的区别及字符串的赋值

    几点区别: 1.一维数组中不一定存放字符串,但字符串一定要存放在一维数组里. 2.字符数组的每一个元素可存放一个字符,但它并不限定最后一个字应该是什么. 3.不可以用赋值语句将字符串常量或其他字符串赋 ...

  5. 【C语言进阶深度学习记录】二十六 C语言中的字符串与字符数组的详细分析

    之前有一篇文章是学习了字符和字符串的,可以与之结合学习:[C语言进阶深度学习记录]十二 C语言中的:字符和字符串 文章目录 1 字符串的概念 1.1 字符串与字符数组 1.2 字符数组与字符串代码分析 ...

  6. android 数组赋值字符串_c语言中的字符数组与字符串

    1.字符数组的定义与初始化 字符数组的初始化,最容易理解的方式就是逐个字符赋给数组中各元素. char str[10]={ 'I',' ','a','m',' ','h','a','p','p','y ...

  7. 【C】C语言数组与字符串(包括:字符串与字符数组)

    在程序设计中,为了方便处理,通常把具有相同类型的若干变量按有序的形式组织起来.这些按序排列的同类数据元素的集合称为数组.在C语言中,数组属于构造数据结构.一个数组可以分解成多个数组元素,这些数组元素可 ...

  8. c语言中字符串数组应用,C语言中字符变量字符串和字符数组应用.doc

    C语言中字符变量字符串和字符数组应用 字符变量(type`char`?字符串(string)和字符数组(type`char`arrary)是C语言中非常重要的结构成分,也是应用编程中常发生混淆?导致错 ...

  9. C语言之字符串探究(一):字符串与字符数组

    相关博文:C++之char和string字符串类探究 相关博文:C语言之数组探究(一):定义.大小.初始化.访问和三要素 相关博文:C语言之字符串探究(一):字符串与字符数组 相关博文:C语言之字符串 ...

最新文章

  1. Files 的值“ .mine”无效。路径中具有非法字符
  2. PAT 10-2 删除字符串中的子串
  3. UVa11107 - Life Forms(后缀数组)
  4. 从排序数组中删除重复项
  5. .NET运行时中的监测和可观测性
  6. C++\Python\Qt工作笔记-读取txt文件查找某行是否包含keyWord
  7. python 解析模块脚本_Python pexpect模块及shell脚本except原理解析
  8. 背景铺满整个页面并且自适应
  9. 生成用于ASP.NET Web API的TypeScript客户端API
  10. 公司顾问岗位职责_【热门推荐】泉州奥育特教育科技有限公司
  11. JavaScript基本数据类型和引用数据类型
  12. 有佳文档管理v2.03
  13. R语言绘制流程图(一)
  14. 我的Android第五章:通过Intent实现活动与活动之间的交互
  15. codevs 1044 拦截导弹
  16. 【用pandas_alive几行代码绘制竞赛动图】10.新南威尔士州 COVID 可视化(测试代码+数据集+绘图参数解析)
  17. IoT当前最重要的机遇,全面解读专为边缘计算而生的EdgeX Foundry
  18. 终于等到了,十位Java架构师整理的“阿里P7”养成计划
  19. Unity 关于小地图的制作
  20. Kubernetes 核心概念介绍

热门文章

  1. docker compose mysql_docker-compose部署MySQL
  2. 查询列名在哪张表_SQL—多表查询
  3. c语言删除一个字符指令,【C语言】实现一个基于命令行的文本编辑器
  4. Docker容器化部署python
  5. idea修改jdk的版本号
  6. 安卓案例:利用单选按钮切换碎片
  7. Spring框架学习笔记04:初探Spring——采用Java配置类管理Bean
  8. 大数据学习笔记26:MR案例——双重排序(先按月份升序,再按利润降序)
  9. 【faebdc的模拟赛】T2分组
  10. 【codevs2144】砝码称重2,哈希什么的都去死吧