请分析,下述代码的输出结果:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *p1="China";
char *p2,*p3;
p2=(char *)malloc(20);
memset(p2,0,20);
//printf("strlen:%d",strlen(p1));
while(*p2++=*p1++);
printf("%s\n",p2);
getch();
}
答案是:输出为空。
解析:
void *memset(void *s, int ch, size_t n);
函数解释:将s中前n个字节替换为ch并返回s; memset:作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法。
一般用法:memset(buffer, 0, sizeof((char)*20));
对于语句
memset(p2,0,20);
这意味着什么呢?p2为char * 类型。每一个char类型赋值int型0。记得ASCII中0号对应着谁么?对着着NUL。
我们知道格式化输入和输出的%s是遇到第一个‘\0’ 就会停止了。还有一个就是int 的0.其实就是NUL。
也就是说p2指着分配的这20个字节的空间。里面全都是结束符。当然这个东西是肯定无法输出的了。
while(*p2++=*p1++);
这个语句,也是非常的匪夷所思。
while后面难道不是条件判断么?判为1,进入while的体进行执行,否则不执行while的体。
我的答案是:while(0or非0)
在执行前,先判断括号里的式子,如果需要计算,就计算,比如这里,就要有三种计算,其实是5次计算机,两次自加,两次取值,
还有一次赋值。
没错,赋值是有返回值的。返回值就是赋值语句的左侧的值。如果是本体中的字符,返回ASCII码。
不要不信哥。
看如下代码:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *p1="China";
char *p2,*p3;
int a,b;
p2=(char *)malloc(20);
memset(p2,0,20);
//p2[19]=0;
//printf("strlen:%d",strlen(p1));
//while(printf("%d\n",(*p2++=*p1++)));
//a=(*p2++=*p1++);
b=printf("%d",(*p2++=*p1++));
printf("b:%d\n",b);
b=printf("%d",(*p2++=*p1++));
printf("b:%d\n",b);
b=printf("%d",(*p2++=*p1++));
printf("b:%d\n",b);
b=printf("%d",(*p2++=*p1++));
printf("b:%d\n",b);
b=printf("%d",(*p2++=*p1++));
printf("b:%d\n",b);
b=printf("%d",(*p2++=*p1++));
printf("b:%d\n",b);
b=printf("%d",(*p2++=*p1++));
printf("b:%d\n",b);
b=printf("%d",(*p2++=*p1++));
printf("b:%d\n",b);
printf("%s\n",p2);
printf("%s\n",p1);
printf("a:%d",a);
printf("b:%d",b);
getch();
}
卡结果:
自己看吧。前五个数字那是“China”对应的码
刚才讲到了while(0or非0)先计算里面的表达式。
看如下写法
while(printf("%d\n",(*p2++=*p1++)))
呵呵,运行一下,会发现,后面出现的一直是0.
一直没有逃出这个循环。其实printf()也是有返回值的。
返回一个int值,表示被打印的字符数 例如: int a=104; printf(%d",a); printf将返回3,再如: printf("123\n"); printf将返回4哈哈。有趣吧。再走一步,
是不是while(0or非0),括号里面可以运行函数呢?
看如下代码:
#include <stdio.h>
#include <stdlib.h>
int haha(void);
int main()
{
while(haha())
{
printf("success");
}
getch();
}
int haha(void)
{
return 1;
}
没错,一旦运行,满屏幕都是succes
这道题,貌似还有什么没有搞通的地方,如果这本书的没道题都这么弄,不知道什么时候才能把这本书看完。
学无止境啊。
关于*p++的问题:
笔者很讨厌一些人这么写代码,有歧义啊。
但是自增自加的优先级是比取值运算高的。
++(*p):
a=*p;
a=a+1;
function(a);
等同于++*p
(*p)++:
a=*p;
func(a);
a=a+1;
等同于 *p++‘
*(p++):
a=p;
*a;
func(*a);
p=p+1;
等同于*p++;
*(++p):
p=p+1:
a=*p
func(a)
蛋疼,好好看看吧。