先看题:
*
编写一程序P137.C实现以下功能
通过键盘输入两个姓名(约定均为汉字且最多4个汉字),判断并输出二者是否同姓。编程可用素材:printf(“请输入姓名1: “)、printf(“请输入姓名2: “)、
printf(”\n“…”与“…”同姓。\n”…、printf(”\n“…”与“…”不同姓。\n”…。
程序的运行效果应类似地如图1和图2所示,图1和图2中的红色部分是从键盘输入的内容。
请输入姓名1: 张李秀吉
请输入姓名2: 张三
“张李秀吉”与“张三”同姓。
图1 程序运行效果示例
请输入姓名1: 李四菊
请输入姓名2: 张三丰
“李四菊”与“张三丰”不同姓。
*/
此题我看到时是完全不会的,经过我百度并询问大佬,答案及解析如下
#include
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位。
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧