字符串与字符数组

字符串一定是一个char的数组,但char的数组未必是字符串。——以字符’\0’结尾的char数组就是一个字符串,但如果char数组没有以’\0’结尾,那么就不是一个字符串,只是普通字符数组,所以字符串是一种特殊的char数组

两者的区别:
字符串:
1、字符串赋初值用双引号引起来;
2、以隐含的空字符\0结束,占用字节数+1,注意:1字节/字母,2字节/汉字;
3、字符串可以使用%s格式化输出。
普通字符数组:
1、普通的字符数组赋初值用大括号引起来;
2、不包含空字符,占用字节数不需+1;
3、普通字符数组使用%s格式化输出,输出结果会乱码,因为没有’\0’结束符。
例如:

#include <stdio.h>
#include <string.h>
int main(void)
{/*字符数组赋初值*/char cArr[] = {'I','L','O','V','E','C'};/*字符串赋初值*/char sArr[] = "ILOVEC";/*用sizeof()求长度*/printf("cArr的长度=%d\n", sizeof(cArr));printf("sArr的长度=%d\n", sizeof(sArr));/*用printf的%s打印内容*/printf("cArr的内容=%s\n", cArr);printf("sArr的内容=%s\n", sArr);return 0;
}

运行结果为:

如果定义:

 char cArr[] = {'I','L','O','V','E','C','\0'};char sArr[] = "ILOVEC";

那么cArr与sArr就完全相同,都表示同一字符串。

另外,%s格式化输出从当前地址到结束标志’\0’之前的所有字符,如:

#include <stdio.h>
#include <string.h>
int main(){char str[] = "http://c.biancheng.net";printf("%s\n", str); //直接输出字符串printf("%s\n", str+1); //输出从第二个地址到最后的值printf("%s\n", str+2); //输出从第三个地址到最后的值return 0;
}


通过对以上代码的分析,现在我们可以很简单地总结出字符数组和字符串二者之间的区别:
对于字符数组,其长度是固定的,其中任何一个数组元素都可以为 null 字符。因此,字符数组不一定是字符串。
对于字符串,它必须以 null 结尾,其后的字符不属于该字符串。字符串一定是字符数组,它是最后一个字符为 null 字符的字符数组。

字符串数组与字符串指针

字符串数组:

//字符串数组
#include <stdio.h>
#include <string.h>
int main(){char str[] = "http://c.biancheng.net";int len = strlen(str), i;//直接输出字符串printf("%s\n", str); //可以直接输出当前地址(字符串首地址)到结束标志'\0'之前的所有字符//每次输出一个字符for(i=0; i<len; i++){printf("%c", str[i]);}printf("\n");return 0;
}

字符串指针:

//字符串指针
#include <stdio.h>
#include <string.h>int main(){
char *str = "http://c.biancheng.net";
int len = strlen(str), i;//直接输出字符串
printf("%s\n", str); //可以直接输出当前地址(字符串首地址)到结束标志'\0'之前的所有字符
//使用*(str+i)
for(i=0; i<len; i++){
printf("%c", *(str+i));
}
printf("\n");
//使用str[i]
for(i=0; i<len; i++){
printf("%c", str[i]);
}
printf("\n");return 0;
}

运行结果都是:
http://c.biancheng.net

这一切看起来和字符数组是多么地相似,它们都可以使用%s输出整个字符串,都可以使用*或[ ]获取单个字符,这两种表示字符串的方式是不是就没有区别了呢?

有!它们最根本的区别是在内存中的存储区域不一样,字符数组存储在全局数据区或栈区,第二种形式的字符串存储在常量区。全局数据区和栈区的字符串(也包括其他数据)有读取和写入的权限,而常量区的字符串(也包括其他数据)只有读取权限,没有写入权限。

内存权限的不同导致的一个明显结果就是,字符数组在定义后可以读取和修改每个字符,而对于第二种形式的字符串,一旦被定义后就只能读取不能修改,任何对它的赋值都是错误的。

我们将第二种形式的字符串称为字符串常量,意思很明显,常量只能读取不能写入。请看下面的演示:


#include <stdio.h>
int main(){
char *str = "Hello World!";
str = "I love C!"; //正确
str[3] = 'P'; //错误return 0;
}

这段代码能够正常编译和链接,但在运行时会出现段错误(Segment Fault)或者写入位置错误。
第4行代码是正确的,可以更改指针变量本身的指向;第5行代码是错误的,不能修改字符串中的字符。

到底使用字符数组还是字符串常量
在编程过程中如果只涉及到对字符串的读取,那么字符数组和字符串常量都能够满足要求;如果有写入(修改)操作,那么只能使用字符数组,不能使用字符串常量。

最后我们来总结一下,C语言有两种表示字符串的方法,一种是字符数组,另一种是字符串常量(用指针表示),它们在内存中的存储位置不同,使得字符数组可以读取和修改,而字符串常量只能读取不能修改。

C语言—字符串与字符数组,字符串数组与字符串指针的区别相关推荐

  1. php把字符串指定字符分割成数组

    <?php $str="1|2|3|4|5|"; $var=explode("|",$str); print_r($var); ?> $var=ex ...

  2. python统计字符在文件中出现的次数_python字符串中字符出现次数(python获取字符串个数)...

    今天要说的是Python的字符串函数还是很方便的,只需要调用 count() 方法即可. 最近,我在一个网站上看到了一个自然语言处理课程.我详细解释了一些方法的使用,用例很容易理解,所以我想通过我的博 ...

  3. java 字符字节数组_Java字符串与字符、字节数组知识点总结

    (1)用字符数组创建字符串对象,String类中有两个有字符数组创建字符串对象的构造的方法: String(char [ ])该构造方法用指定的字符数组创建构造一个字符串对象: String (cha ...

  4. c语言如何生成字符型动态数组,C语言构建动态数组完整实例

    C语言构建动态数组完整实例 本文以一个完整的实例代码简述了C语言构建动态数组的方法,供大家参考,完整实例如下: #include #include int main(void) { int len; ...

  5. string 字符串中字符无效_7.3 C++字符串类 | 使用string输出

    C++字符串类 C++提供了一种新的数据类型:字符串类型,它和char,int类型一样,可以用来定义变量,用一个名字代表一个字符序列,这就是字符串变量. 读者需要明白string并不是C++本身具有的 ...

  6. 字符串查找字符出现次数_查找字符串作为子序列出现的次数

    字符串查找字符出现次数 Description: 描述: It's a popular interview question based of dynamic programming which ha ...

  7. 字符串某个字符修改颜色、给字符串添加

    字符串某个字符修改颜色: UILabel *titleLabel = [[UILabel alloc]init]; titleLabel.font = smallFont; titleLabel.te ...

  8. java 统计字符串中字符个数_java实现统计字符串中字符及子字符串个数的方法示例...

    本文实例讲述了java实现统计字符串中字符及子字符串个数的方法.分享给大家供大家参考,具体如下: 这里用java实现统计字符串中的字符(包括数字.大写字母.小写字母以及其他字符)个数,以及字符串的子字 ...

  9. JavaScript 获取字符串指定字符的数量 JS 获取字符串指定字符的数量

    JavaScript 获取字符串指定字符 //循环对比计数 效率最低 function getCharCount1(str,char){let count= 0;for(let i=0;i<st ...

  10. C语言打印彩色字符——以(枚举法+字符串查找)为例展示

    文章目录 C语言颜色头文件--自制非常简单的调用函数 实战演练--一个基础的枚举变量小程序 牛刀小试--查找字符小程序 C语言颜色头文件--自制非常简单的调用函数 显然,C语言是不会提供打印彩色字符的 ...

最新文章

  1. [国嵌攻略][080][无名管道通讯]
  2. Zuul 查看所有路由路径与filter(过滤器)
  3. 1.java的基础和数据类型
  4. java拷贝文件目录结构_Java如何复制目录_Java基础教程系列
  5. 数字图像处理(四)——图像编码技术(二)
  6. 查linux服务器CPU多少C,在linux 下怎么查看服务器的cpu和内存的硬件信息
  7. 如何开始学习使用TensorFlow?
  8. mysql 并发锁_MySQL的并发控制与加锁分析
  9. EDK2 UDK2018的环境搭建
  10. PS抠发丝简单详细方法
  11. 动态创建弹框el-dialog
  12. Java 中的设计模式详细介绍
  13. 惠普服务器做linux系统安装系统教程,HP刀片服务器安装系统步骤
  14. VLOG短视频必备!24个Ins潮流插画风视频短视频模板
  15. C语言函数:tolower()、toupper字符大小写转换函数。
  16. filecoin/lotus 官方开发文件中文翻译2019.12.17最新版本
  17. 厉害了,我的国百度云资源
  18. 折腾笔记--Linux和Windows10双系统安装的一般步骤(通用)(物理机安装)
  19. IT女性的职业困惑 (1)
  20. Google Map API使用谷歌地图api实现地点搜索功能

热门文章

  1. 如何用百数低代码开发平台实现会议预约?
  2. 互联网求职(算法)-中文简历制作
  3. IOS APP 图标
  4. github汉化注意事项(Chrome)
  5. 一种特殊的线性变换——正交变换
  6. Linux根目录各个文件夹介绍及说明
  7. 少儿python编程课程大纲_1.Python编程-课程教学大纲.doc
  8. 软碟通 UltraISO,虚拟光盘文件的制作,编辑,转换工具,可以直接编辑虚拟光盘或提取文件,打开isz,iso的工具,注册码...
  9. 孝心无价 ——《为了母亲的微笑》序言
  10. 腾讯王巨宏:“未来+教育”,以智能技术助力人才培养新模式