字符数组和结束符/0之间的关系

在C中,字符串其实就是字符数组。C语言中,对字符串就是按字符数组的规律来处理的(ANSI的字符是unsigned char,对宽字符,字符是unsigned short int,即前者1byte,后者2byte)。由于是按数组方式处理的,所以必须知道每个串的实际有效元素到哪里结束,想像图书馆书柜中的格子,书柜尽管有100个格子,但未必要放满100本书,可能是10本、20本,所以不能按格数来算字符串长度(算格数那个就是sizeof()的值),实际放书的数量是动态变化的,所以C语言规定某个标志,告诉处理程序,遇到这个标志,就表示书放到此为止,后面不会有书了,这个标志就是‘\0‘,也是整数0。

C标准库中的字符串处理程序,是只认‘\0‘的,只要没找到‘\0‘,它就认为字符串没有结束,拼命地往后找,这个寻找的过程不理会可能已经超过书柜的格数了(计算机其实很蠢);同样,也可能你在一排书中的中间抽走一本,在那个位置上写上‘\0‘,那么愚蠢的计算机也会认为书到这里为止,它不理会后面其实还有(这是某种截断字符串的技巧)。

其实,只要你明白这种类比,自然知道写程序的时候怎么办。比如,当你明白宽字符是16位整数亦即2字符的时候,就会明白,一个宽字符L‘A‘其实储存有一个字节的0,亦即假如你用常规的ANSI算法来处理这样的字符串,就会很快遇到‘\0‘,后果如何可想而知。

标准库函数strlen(),就是在字符数组中搜寻‘\0‘的简短代码,找到后,把经历过的元素个数返回出来而已。知道这点原理,其实我们并不是必须遵守以‘\0‘为结束符的cz字符串规则的,以-1结束亦未尝不可,自己写一个_strlen()函数,不用strlen()就可以了。C的灵活性,就体现在这里。须知,C语言本身是没有strlen()这样的内置函数的,它其实就只有那些运算符和数据结构构造规则,你所用的库函数,全部是后人写的代码,不是C语言,最纯正的C语言,应该是所有函数都自己写。标准库函数认cz字符串,你完全可以不认,并非因此而说你没使用C语言写程序。

像BASIC类的语言,内部其实也是把字符串作数组看待的(所谓C是基础,也是指的这点原理,用来理解别的语言的实现机制,很可能这种语言是用C制作的),只不过,它不用认‘\0‘作结束符,而把数组的零号元素挪用为字符串长度的记录,所以迫使它的数组计数从1开始,但好处是求数组的有效元素数目不用像C那样遍历数组,而是直接从零号元素读出结果,比遍历快得多——当使用单字节字符系统时,单字节最大值是256,所以很多旧式的语言,字符串最大容量是255或254个字符,就很好理解了。(wsj注:剩余空间用来存放‘\0‘)

我们现在再看另一个例子:char* strcat(char* s1, const char* s2)这个函数,是字符串接驳,它的作用是把s2追加在s1的末尾,形成新的字符串。仍然使用上面书柜的例子,既然要在s1的柜子中放入更多的书,那么s1的格子数必须要能容纳全部的书,这是必然的,而书柜是在建造时就造好了的,所以创建s1的时候,首先要考虑这个问题,别指望C库函数会替你想这些,为了高效,它完全不检查这个,闷头就把数据扔过去,它的高效是这样来的(别的语言,为了完成任务,它会智能地做各种动作把任务完成,而C只是做错了报告一声“出错了”就干脆逃跑,被系统杀掉)。在容量满足条件的基础下,函数的动作,首先是找到s1的‘\0‘位置,然后从s2中逐个把数据复制过来,注意此时必须把‘\0‘覆盖掉并写上新的‘\0‘,原因在上面说过了。所以,现在返回头看看函数的原型,它的s1是char*,表明这个字符串是可以被修改的,事实上它必须改这个,而s2是const char*,表明它不需要改动s2,返回的正是s1指针。

那么,假如要把两个被记录在只读储存空间的字符串接驳成一个,或者已经无法再修改s1的尺寸了,你该怎么做?用strcat是不要指望了,因为此时无法修改s1,你必须自己写一个,用动态申请内存。

学会语法很简单,但面对具体的情形,如何处理,这才是最需要学习的,假如连这点原理都不知道,那就悲催了,实际上这些动作用不了多复杂的算法、数据结构,但很多人就死在这种地方!现在明白学C到底要学什么了吗?

实例:

char s[6]={‘h‘,‘e‘,‘l‘,‘l‘,‘o‘};
char s[6]={"hello"};
char s[6]="hello";

字符数组和字符串的区别:字符数组的每个元素中可存放一个字符,(像这个char s[6]={‘h‘,‘e‘,‘l‘,‘l‘,‘o‘};
)但他不限定最后一个字符应该是什么,存储空间有剩余系统补‘\0’。而字符串则要求最后一个必须是‘\0’做为结束标示。在字符数组中可以存放字符串。
char s[6]={"hello"};看这个为什么是s[6],而不是s[5]呢?因为,字符串后面以‘\0’为结束标示,这个是系统补的,不用手动输入。但是必须要给它留一个存储空间。这个‘\0’它占用存储空间,但是不算字符串长度。

(wsj注:在申请字符串存储空间时要考虑末尾的结束符‘\0‘空间,即在单字节字符系统中要多申请一个字节。)

转自http://bbs.bccn.net/thread-398526-2-1.html

时间: 2024-10-21 06:08:44

字符数组和结束符/0之间的关系的相关文章

C++string,char* 字符数组,int类型之间的转换

string.int 常见类型之间相互转换 int & string 之间的转换 C++中更多的是使用流对象来实现类型转换 针对流对象 sstream实现 int,float 类型都可以实现 #include <sstream> //int convert to string void int2str(const int &int_temp,string &string_temp){ stringstream s_stream; s_stream<<int_

详解php中空字符串和0之间的关系

$_x=$row["x"];$_y=$row["y"];if(isset($_x) && isset($_y)){if($row["y"] == 0 || $row["x"] == 0){$d=$this->getDistance($row["y"],$row["x"],$y,$x);}elseif(!empty($row["y"]) &

转:细说一个汉字等于几个字符,以及汉字,字符,字节,位之间的关系

全文主旨总结: 一:        1个汉字 = 1个字 = 1个字符 二:        1个字符 = 1个字节 = 8bit(ACSII码下) 三:        1个字符 = 2个字节 = 16bit(Unicode码下) 四:        一般在处理汉字时,会默认将 编码方式调整为Unicode码,因为这样 数据容纳范围更大,不易出现乱码. 参考资料: 网址: http://www.lovetofang.net/index.php/22.html

C语言学习笔记:19_数组-字符数组与字符串(常用字符串函数)

/* * 19_数组-字符数组与字符串.c * * Created on: 2015年7月7日 * Author: zhong */ #include <stdio.h> #include <stdlib.h> #include <string.h> /** *一:字符数组:就是存放字符的char[]数组 * 由于c语言中没有像java,C#中的String(字符串),只有存放字符 的字符型数组当字符串使用(java中的String类也是对字符数组进行封闭的). * *

一种循环C字符数组的骚操作

#include <stdio.h> #include <stdlib.h> int main() { char wenwa[] = "程劲小盆友在做什么"; int _len = 0; while (wenwa[_len]) { printf("%c", wenwa[_len]); _len++; } printf("\n"); system("pause"); return EXIT_SUCCESS

字符数组初窥

什么是字符数组 字符数组使用字符的形式保存数组(实质上就是将单个字符利用数组的方式保存起来) 数组:采用int,float,double类型初始化 字符数组:采用char类型初始化 int i[]={1,2,3}; char ch[]={'h','e','l','l','o'}; 字符数组与字符串的区别 我们通常意义上说的字符串是类似于“hello”这样用双引号引起来的字符集.二者的区别主要集中在定义和赋值上. 在C中对字符串并没有明确的划分,一般使用字符数组来初始化字符串并赋值.即 char

字符串和字符数组之间的转换

package String; /* * 写了一个字符串和字符数组之间转换的例子 * 总结:将字符串转变为字符数组 :public char[] toCharArray() * 直接将一个字符数组变成一个字符串 public String (char[] value) 这个是构造函数啊,可以直接new 并为属性赋值啊. */ public class StringDemo2 { public static void main(String[] args) { String s = "hellow

字符数组和string判断是否为空行 NULL和0 namespace变量需要自己进行初始化

string 可以这样判断空行input !="" 字符数组可以通过判断第一个元素是否为空字符'\0',是的话为空行arrar[0]=='\0':或者用长度strlen(char arrar)==0特别注意这两个arrar[0]==0:arrar[0]==NULL:因为指向了空指针,空指针指向NULL,NULL在VS这个IDE上,代表0,所以上述成立 NULL用于指针和对象,0用于数值 在不同的系统中,NULL并非总是和0等同,NULL仅仅代表空值,也就是指向一个不被使用的地址,在大多

将一段含有0的字符数组赋给string

string有个成员函数,assign() 可以这样: 1 string str; 2 str.assign(temp, sizeof(temp)); 将一段含有0的字符数组赋给string,布布扣,bubuko.com