指针与字符串的秘密&赋值运算返回值&printf()返回值

来源:互联网 发布:react php 编辑:程序博客网 时间:2024/06/06 16:48

[cpp] view plaincopy
  1. 请分析,下述代码的输出结果:  
  2. #include <stdio.h>  
  3. #include <stdlib.h>  
  4. int main()  
  5. {  
  6.     char *p1="China";  
  7.     char *p2,*p3;  
  8.   
  9.     p2=(char *)malloc(20);  
  10.   
  11.     memset(p2,0,20);  
  12.   
  13.     //printf("strlen:%d",strlen(p1));  
  14.   
  15.     while(*p2++=*p1++);  
  16.   
  17.     printf("%s\n",p2);  
  18.   
  19.   
  20.   
  21.   
  22.   
  23.   
  24.     getch();  
  25. }  
答案是:输出为空。


解析:

void *memset(void *s, int ch, size_t n);   

函数解释:将s中前n个字节替换为ch并返回s;  memset:作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法。


一般用法:memset(buffer, 0, sizeof((char)*20));


对于语句

[cpp] view plaincopy
  1. memset(p2,0,20);  
这意味着什么呢?p2为char * 类型。每一个char类型赋值int型0。记得ASCII中0号对应着谁么?对着着NUL。

我们知道格式化输入和输出的%s是遇到第一个‘\0’ 就会停止了。还有一个就是int 的0.其实就是NUL。

也就是说p2指着分配的这20个字节的空间。里面全都是结束符。当然这个东西是肯定无法输出的了。

[cpp] view plaincopy
  1. while(*p2++=*p1++);  
这个语句,也是非常的匪夷所思。

while后面难道不是条件判断么?判为1,进入while的体进行执行,否则不执行while的体。

我的答案是:while(0or非0)

在执行前,先判断括号里的式子,如果需要计算,就计算,比如这里,就要有三种计算,其实是5次计算机,两次自加,两次取值,

还有一次赋值。

没错,赋值是有返回值的。返回值就是赋值语句的左侧的值。如果是本体中的字符,返回ASCII码。

不要不信哥。

看如下代码:

[cpp] view plaincopy
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. int main()  
  4. {  
  5.     char *p1="China";  
  6.     char *p2,*p3;  
  7.     int a,b;  
  8.   
  9.     p2=(char *)malloc(20);  
  10.   
  11.     memset(p2,0,20);  
  12.     //p2[19]=0;  
  13.   
  14.     //printf("strlen:%d",strlen(p1));  
  15.   
  16.  //while(printf("%d\n",(*p2++=*p1++)));  
  17.     //a=(*p2++=*p1++);  
  18.     b=printf("%d",(*p2++=*p1++));  
  19.     printf("b:%d\n",b);  
  20.     b=printf("%d",(*p2++=*p1++));  
  21.     printf("b:%d\n",b);  
  22.     b=printf("%d",(*p2++=*p1++));  
  23.     printf("b:%d\n",b);  
  24.     b=printf("%d",(*p2++=*p1++));  
  25.     printf("b:%d\n",b);  
  26.   
  27.     b=printf("%d",(*p2++=*p1++));  
  28.     printf("b:%d\n",b);  
  29.     b=printf("%d",(*p2++=*p1++));  
  30.     printf("b:%d\n",b);  
  31.     b=printf("%d",(*p2++=*p1++));  
  32.     printf("b:%d\n",b);  
  33.     b=printf("%d",(*p2++=*p1++));  
  34.     printf("b:%d\n",b);  
  35.   
  36.     printf("%s\n",p2);  
  37.     printf("%s\n",p1);  
  38.   
  39.     printf("a:%d",a);  
  40.   
  41.     printf("b:%d",b);  
  42.   
  43.   
  44.   
  45.   
  46.   
  47.   
  48.     getch();  
  49. }  
卡结果:

自己看吧。前五个数字那是“China”对应的码

刚才讲到了while(0or非0)先计算里面的表达式。

看如下写法

[cpp] view plaincopy
  1. 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),括号里面可以运行函数呢?

看如下代码:

[cpp] view plaincopy
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. int haha(void);  
  4. int main()  
  5. {  
  6.   
  7.   
  8.   
  9. while(haha())  
  10. {  
  11.     printf("success");  
  12. }  
  13.   
  14.   
  15.   
  16.   
  17.     getch();  
  18. }  
  19. int haha(void)  
  20. {  
  21.     return 1;  
  22.   
  23. }  

没错,一旦运行,满屏幕都是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)


蛋疼,好好看看吧。