c语言截断符 汉字的输入输出与比较

先看题:
*
 编写一程序P137.C实现以下功能
  通过键盘输入两个姓名(约定均为汉字且最多4个汉字),判断并输出二者是否同姓。编程可用素材:printf(“请输入姓名1: “)、printf(“请输入姓名2: “)、
printf(”\n“…”与“…”同姓。\n”…、printf(”\n“…”与“…”不同姓。\n”…。
  程序的运行效果应类似地如图1和图2所示,图1和图2中的红色部分是从键盘输入的内容。
请输入姓名1: 张李秀吉
请输入姓名2: 张三

“张李秀吉”与“张三”同姓。

图1 程序运行效果示例

请输入姓名1: 李四菊
请输入姓名2: 张三丰

“李四菊”与“张三丰”不同姓。
*/
此题我看到时是完全不会的,经过我百度并询问大佬,答案及解析如下
#include <stdio.h>
int main()
{
char name1[9],name2[9]; //一个汉字占两位,四字名字需要8位,此外还需要一位来填充截断符;
printf(“name1:%p\nname2:%p\n”,name1,name2);

printf("请输入姓名2: ");
scanf("%s",name2);		//数组的本质是一块内存,而scanf读取输入的时候只需要知道首地址即可
printf("请输入姓名1: ");
scanf("%s",name1);
if (name1[0]==name2[0] && name1[1]==name2[1])	//判断前两位字符是否一致,即判断第一个汉字(姓氏)是否一致。
	printf("\n“%s”与“%s”同姓。\n",name1,name2);
else
	printf("\n“%s”与“%s”不同姓。\n",name1,name2);

return 0;

}
此处的截断符即ASCII表中的第一个,是一个空字符(Null),这个对应的就是 ‘\0’ ,其在ASCII码表中对应的是0。此外,在判断字符串是否结束的标志时,就是通过判断是否遇到了 ‘\0’ ,如果遇到则表示字符串结束。
说了这么多,就有人要问了,这跟上面的代码有什么关系呢?当然有。
如果将申请的name1与name2两个数组中的位数从9位换成8位,理论是没有毛病的,因为这题给的名字里面字数最多也就四个字,一个汉字占据8位,完全够了。
然而,vc6++对于连续声明的两个数组,它们的内存地址是连续的,scanf又不会对读取的长度做安全检查,此时如果用%p输出它们的地址,(在两个name数组声明下面来一行:printf(“name1:%p\nname2:%p”,name1,name2);),就能找出两个数组的首地址:
name1:0019FF28
name2:0019FF20
显而易见,name2的地址小,name1的地址大,计算机在读取name2的时候,因为读取的第九个字符变成了\0,而他后面的第九个字符就是name1的起始地址,因此,在输出name1的时候,直接就没有了,因为第一个字符被vc6++编译器自动赋值为“\0”(这好像是vc6++本身的问题,c6++对于连续声明的两个数组,它们的内存地址是连续的)。
因此,在申请两个数组时,name1和name2才会给赋成9位。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值