合并函数strcat()运用时字符串数组中为0的元素难道被舍去?
#include
int main()
{
char s1[20] = "Hello";
char s2[6] = "World";
strcat (s1,s2);
puts(s1);
}
难道定义数组s1不会有0在后面,s2也有0啊(难道大写占两个字符?就算是两个s1后面也要跟很多0啊)
定义数组不是多余的元素被赋予0吗?难道字符串数组不是这样的? |
免责声明:本内容仅代表回答会员见解不代表天盟观点,请谨慎对待。
版权声明:作者保留权利,不代表天盟立场。
|
|
|
|
s1后面是有0:
你说得没错,s1就是char数组,定义时未初始化的部分为0,并且字符串后面会加上一个'\0'代表字符串结尾。所以s1的开头的5个元素是'H' 'e' 'l' 'l' 'o',后面一个'\0',剩下的都是0。
s2也是同样的道理,当然s2的大小正好容纳下W o r l d这5个字符和一个'\0',所以后面没有多余的0了。
你想问的是不是:为什么strcat函数就知道要把s2中的字符串接在s1中最后一个字符'o'后面?
C语言规定字符串的形式就是:内存中的连续存放的一串char,并且用'\0'代表字符串的结束。
所以strcat函数——包括库中所有处理字符串的函数——都是这样判断的:strcat从s1中读到第一个'\0',它就知道这串字符串到这里就结束了,然后会把s2中的字符依次拷贝到s1中的这个'\0'及后面的内存中,直到拷贝到s2中的'\0',函数就知道s2所表示的字符串也结束了,最后它会保证这个新连接成的字符串也是以'\0'做结尾的(必须以'\0'标志字符串结束)。
这样看,你也可以说是s1中后面的0被舍去了。 那些0虽然在s1数组中,但它们根本就不算是字符串的一部分。库中的字符串处理函数永远是用'\0'来判断字符串是否到结尾的。
而且从strcat函数工作流程的描述中你也能看出来:函数只是在不断将字符拷贝过来,直到'\0'才结束拷贝,函数根本不管到底要拷贝多少个! 这才是为什么要求s1有足够大的大小来容纳连接后的字符串,并且这一点需要由程序员来保证! |
|
|
|
|
不好意思,这几天加班,这会儿才得空,回答下你的问题:
第一个问题:
我尽量不敷衍地告诉你记住就可以了,而会尝试从原理讲明白为什么初始化成'\0'而不是'0'
首先你得先了解一个叫ASSCII(美国信息交换标准代码)的东西,详细定义可以看下wiki或者百度百科:
引用百度百科图片:
在C语言中char类型占1byte,即8bit,能够表示的范围是00000000~11111111(二进制),即0~255(十进制),实际存储的就是ASCII码
比如'0'在上图表示48(十进制)即00110000(二进制)
再比如'\0'在上图表示0(十进制)即00000000(二进制)
发现了吗?char类型的0实际上是00000000即我们平常所说的'\0',显然即便是你设计也不会设计成默认补00110000('0')吧?
这下你理解了吧?至于为什么初始化为'\0',这个大概是编译器编译、链接、生成可执行代码后,由计算机执行时会自动为没有赋值的字符补'\0'吧,至于更加深入的比如机器执行二进制代码和编译器gcc的编译过程就没有研究过了。
第二个问题:
是的,不好意思笔误指向\0
第三个问题:
*在C语言中是指针,是C/C++语言的特色也是难点,简单说就是个8bit数字(64位机器),表示内存地址,
chars1[20]="Hello";char*dest=s1;char*tmp=dest;//上一行代码含义//s1://Hello\0\0\0\0\0...\0//^//|//*tmp,*dest上面这段注释表示char类型的指针tmp和char类型的指针dest都指向字符数组s1的首地址,有关指针的详细的教程你只要继续深入地往下学,就都会明白了,要想完全理解函数strcat的源码,需要你理解指针,我只是简单告诉你含义 |
|
|
|
|