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

本文详细解析了一段使用C语言实现的代码片段,重点探讨了内存分配、初始化、字符串拷贝及字符串输出的过程。通过实例分析,揭示了`memset`函数的作用、内存初始化的原理以及字符串处理中的常见陷阱。特别强调了`while`循环中表达式的计算过程,揭示了`printf`函数返回值的利用方式,并通过一系列实验代码展示了这一原理的应用。文章旨在帮助开发者深入理解C语言中内存管理和字符串处理的关键概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

请分析,下述代码的输出结果:
#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)


蛋疼,好好看看吧。









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值