生活服务
C语言的一些“骚操作”及其深层理解_c语言 xb,怎么入门Golang
2024-12-27 02:35  浏览:101

int fputc(int ch, FILE *f)
{
while((USART1->SR&0x40)==0);
{
USART1->DR = (u8) ch;
}

return ch;
}

fputc中将ch通过USART1发出。这样,我们在调用printf的时候,相应的信息就会从USART1打印出来。

“上面你说的这些,我都知道,有什么新鲜的!”确实,通过串口打印信息是我们司空见惯的。那么,下面的fputc你见过吗

int fputc(int ch, FILE *f)
{
LCD_DispChar(x,y,ch);
x++;
if(x>=X_MAX)
{
x=0;y++;

if(y>=Y_MAX)*
{
y=0;
}
}
return ch;
}

这个fputc将字符显示在了液晶上(同时维护了字符的显示位置信息,这样当我们调用printf的时候,信息会直接显示在液晶上。

说白了,fputc 就是对数据进行了定向输出。这样我们可以把 printf 变得更灵活,来应对更多样的应用需求。在振南经历的项目中,曾经有过这样的情况:单片机有多个串口,串口1用于打印调试信息,串口2与ESP8266 WIFI模块通信,串口3与SIM800 GPRS模块通信。3个串口都需要格式化输出,但printf只有一个,这该怎么办?我们解决方法是,修改fputc使得printf可以由3个串口分时复用,具体实现如下

unsigned char us=0;

int fputc(int ch,FILE *f)
{
switch(us)
{
case 0:
while((USART1->SR&0x40)==0);
USART1->DR=(u8)ch;
break;

case 1:
while((USART2->SR&0x40)==0);
USART2->DR=(u8)ch;
break;

case 2:
while((USART3->SR&0x40)==0);
USART3->DR=(u8)ch;
break;
}

return ch;
}

在调用的时候,根据需要将us赋以不同的值,printf就归谁所用了。

#define U_TO_DEBUG us=0;
#define U_TO_ESP8266 us=1;
#define U_TO_SIM800 us=2;

U_TO_DEBUG
printf(“hello world!”);

U_TO_ESP8266
printf(“AT ”);

U_TO_SIM800
printf(“AT ”);

七、关于浮点数的传输

unsigned short a=0x1234;

UART_Send_Byte(((unsigned char *)&a)[0]);

UART_Send_Byte(((unsigned char *)&a)[1]);

也就是将构成整型的若干字节顺序发送即可。当然,接收方一定要知道如何还原数据,也就是说,它要知道自己接收到的若干字节拼在一起是什么类型,这是由具体通信协议来保障的。

unsigned char buf[2];
usnigned short a;

UART_Receive_Byte(buf+0);
UART_Receive_Byte(buf+1);

a=(*(usnigned short *)buf);

OK,关于整型比较容易理解。但换成float,很多人就有些迷糊了。因为float的数值表达方式有些复杂。有些人使用下面的方法来进行浮点的发送

float a=3.14;

char str[10]={0};

ftoa(str,a); //浮点转为字符串 *即3.14*转为"3.14"

UART_Send_Str(str); //**通过串口将字符串发出

很显然,这种方法非常的“业余”。

还有人问我:“浮点小数字前后的数字可以发送,但是小数点怎么发?”这赤裸裸的体现了他对浮点类型的误解。

不要被float数值的表象迷惑,它实质上只不过是4个字节而已,如下图所示

所以,正确的发送浮点数的方法是这样的

float a=3.14;

UART_Send_Byte(((unsigned char *)&a)[0]);

UART_Send_Byte(((unsigned char *)&a)[1]);

UART_Send_Byte(((unsigned char *)&a)[2]);

UART_Send_Byte(((unsigned char *)&a)[3]);

接收者将数据还原为浮点

unsigned char buf[4];
float a;

UART_Receive_Byte(buf+0);

UART_Receive_Byte(buf+1);

UART_Receive_Byte(buf+2);

UART_Receive_Byte(buf+3);

a=*((float *)buf);

其实我们应该发现数据类型的实质:不论是什么数据类型,它的基本组成无非就是内存中存储的若干个字节。只是我们人为的赋予了这些字节特定的编码方式或数值表达。看穿了这些,我们就认识到了数据的本质了,我们甚至可以直接操作数据。

八、关于数据的直接操作

直接操作数据?我们来举个例子:取一个整型数的相反数。一般的实现方法是这样的

int a=10;
int b=-a; //-1*a;

这样的操作可能会涉及到一次乘法运算,花费更多的时间。当我们了解了整型数的实质,就可以这样来作

int a=10;

int b=(~a)+1;

这也许还不足以说明问题,那我们再来看一个例子:取一个浮点数的相反数。似乎只能这样来作

float a=3.14;

float b=a*-1.0;

其实,我们可以这样来作

float a=3.14;
float b;

((unsigned char *)&a)[3]^=0x80;
b=a;

没错,我们可以直接修改浮点在内存中的高字节的符号位。这比乘以-1.0的方法要高效的多。

当然,这些操作都需要你对 C 语言中的指针有炉火纯青的掌握。

九、浮点的四舍五入与比较

我们先说第一个问题:如何实现浮点的四舍五入?很多人遇到过这个问题,其实很简单,只需要把浮点+0.5然后取整即可。OK,第二个问题:浮点的比较。这个问题还有必要好好说一下。首先我们要知道,C语言中的判等,即==,是一中强匹配的行为。也就是,比较双方必须每一个位都完全一样,才认定它们相等。这对于整型来说,是可以的。但是float类型则不适用,因为两个看似相等的浮点数,其实它们的内存表达不能保证每一个位都完全一样。这个时候,我们作一个约定:两个浮点只要它们之差m足够小,则认为它们相等,m一般取10e-6。也就是说,只要两个浮点小数点后6位相同,则认为它们相等。也正是因为这个约定,很多C编译器把float的精度设定为小数点后7位,比如ARMCC(MDK的编译器)。

float a,b;

if(a==b)
… //**错误

if(fabs(a-b) <= 0.000001)
…//**正确

十、出神入化的for循环

for循环我们再熟悉不过了,通常我们使用它都是中规中矩的,如下例

int i;

for(i=0;i<100;i++)
{…}

但是,如果我们对for循环的本质有更深刻的理解的话,就可以把它用得出神入化。

for后面的括号中的东西我称之为“循环控制体”,分为三个部分,如下图所示:A、B、C三个部分,其实随意性很大,可以是任意一个表达式。所以,我们可以这样写一个死循环

for(1;1;1) //1**本身就是一个表达式:常量表达式
{

}

当然,我们经常会把它简化成

for(;😉
{

}

既然循环控制体中的A只是在循环开始前作一个初始化的操作,那我这样写应该也没毛病

int i=0;

for(printf(“Number: ”);i<10;i++)
{
printf(" %d ",i);
}

B是循环执行的条件,而C是循环执行后的操作,那我们就可以把一个标准的if语句写成for的形式,而实现同样的功能

if(strstr(“hello world!”,“abc”))
{
printf(“Find Sub-string”);
}
char *p;

for(p=strstr(“hello world!”,“abc”);p;p=NULL)
{
printf(“Find Sub-string”);
}

以上的例子可能有些鸡肋,“一个if能搞定的事情,我为什么要用for?”,没错。我们这里主要是为了解释for循环的灵活用法。深入理解了它的本质,有助于我们在实际开发中让工作事半功倍,以及看懂别人的代码。

以下我再列举几个for循环灵活应用的例子,供大家回味。例1

char *p;

for(p=“abcdefghijklmnopqrstuvwxyz”; printf§; p++)
printf(“ ”);

提示:printf我们太熟悉了,但有几个人知道printf是有返回值的?输出应该是怎样的

例2

char *p;
unsigned char n;

for(p=“ablmnl45ln”,n=0;((*p==‘l’)?(n++):0),*p;p++);

提示:还记得C语言中的三目运算和逗号表达式吗?n应该等于几

例3

unsigned char *index=“C[XMZA[C[NK[RDEX@”;

char *alphabet="EHUIRZWXABYPOMQCTGSJDFKLNV ";

int i=0;

for(😭(‘@’!=index[i])?1:(printf(“!!Onz ”),0));i++)
{
printf(“%c”,alphabet[index[i]-‘A’]);
}

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Go语言工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Golang知识点,真正体系化

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导,让我们一起学习成长

cW1-1712959914313)]
[外链图片转存中…(img-ZZdXfR3W-1712959914313)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Golang知识点,真正体系化

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Go
[外链图片转存中…(img-sdigNb79-1712959914314)]

    以上就是本篇文章【C语言的一些“骚操作”及其深层理解_c语言 xb,怎么入门Golang】的全部内容了,欢迎阅览 ! 文章地址:http://ww.kub2b.com/tnews/2120.html
     栏目首页      相关文章      动态      同类文章      热门文章      网站地图      返回首页 企库往资讯移动站 http://ww.kub2b.com/mobile/ , 查看更多   
最新文章
电信怎么设置呼叫转移功能,座机怎么设置呼叫转移功能oppo手机怎么设置呼叫转移「电信怎么设置呼叫转移功能,座机怎么设置呼叫转移功能」
最佳答案1.我们拨通10000,然后再按照语音提示接通人工服务; 2.然后我们再让客服来开通呼叫转移这个功能,还有其他两个选项,但
把强大的chrome浏览器安装到手机上,并支持电脑版的各种扩展CRX插件chrome手机版「把强大的chrome浏览器安装到手机上,并支持电脑版的各种扩展CRX插件」
发现了一款强大的手机版chrome浏览器,这个绝对不是应用市场里面的那个chrome,应用市场里的chrome不够强大,而且无法安卓扩展插
红警大作战尤里的复仇红警复仇手机版「红警大作战尤里的复仇」
红警大作战尤里的复仇是一款经典游戏的延续之作,经典的游戏红色警戒相信大家都玩过,这款游戏是在经典的基础上加以进化,让玩家
超千亿元回购增持再贷款!A500ETF今日低开高走,实时成交额突破9000万元
消息面上,自去年10月18日股票回购增持再贷款政策工具正式设立至今已半年,上市公司和主要股东积极响应。据Wind资讯数据统计,截
折叠手机铰链耐久度对决!三星超越摩托罗拉,OPPO表现引人瞩目摩托罗拉折叠手机「折叠手机铰链耐久度对决!三星超越摩托罗拉,OPPO表现引人瞩目」
前几日,有外网博主进行了一项“利好消费者但很无聊”的实验,就是直播两款折叠手机的铰链耐用度,型号分别是对三星Galaxy Z Fli
金饰价格最高突破1000元/克!上海金ETF(518600)开盘延续涨势,已连续12日获资金布局,冲击5连涨
【国际金价续创历史新高,金饰价格突破1000元/克】消息面上,受国际金价继续上涨影响,国内各金饰品牌挂牌价格也随之攀升至历史
手机拍摄屏幕时条纹的问题与解决:揭秘摩尔纹现象及拍摄技巧手机拍电脑屏幕有条纹怎么解决「手机拍摄屏幕时条纹的问题与解决:揭秘摩尔纹现象及拍摄技巧」
在现代智能手机普及的今天,拍摄屏幕内容已经成为许多用户日常生活中的一部分。然而,在这一过程中,时常会出现一现象:拍摄的照
“全球新一代豪华中大型电混轿车”推动“豪华平权”
4月10日,“全球新一代豪华中大型电混轿车”星耀8启动预售。新车推出搭载雷神EM-P超级电混和雷神EM-i超级电混的双动力版本,共计
苹果手机应用宝在哪里苹果手机下载应用宝「苹果手机应用宝在哪里」
对于许多苹果手机用户来说,应用宝这款应用商店并不陌生。作为腾讯旗下的手机应用商店,应用宝以其丰富的应用资源和便捷的下载方
倒班排班助手排班软件手机版「倒班排班助手」
倒班排班助手app方便用户的工作管理非常的适合哪些工作需要轮班的人员,一键的设置非常的便捷,自定义班次,还可以便捷的进行备