历史上的今天
返回首页

历史上的今天

今天是:2024年09月14日(星期六)

正在发生

2021年09月14日 | jz2440裸机开发与分析:串口编程3之printf解析

2021-09-14 来源:eefocus

测试代码:

 #include 

 

void printf_test(void)

{

printf("hello wordn");

printf("This is www.100ask.org   my_printf testn") ;

printf("test char           =%c,%cn", 'A','a') ;

printf("test decimal number =%dn",    123456) ;

printf("test decimal number =%dn",    -123456) ;

printf("test hex     number =0x%xn",  0x55aa55aa) ;

printf("test string         =%sn",    "www.100ask.org") ;

}


int main(int argc ,char *argv[])

{

printf_test();

return 0;

}


效果:


hello word

This is www.100ask.org   my_printf test

test char           =A,a

test decimal number =123456

test decimal number =-123456

test hex     number =0x55aa55aa

test string         =www.100ask.org


下面对printf进行分析

printf函数原型

int printf(const char *format, …);

format :固定参数

… :可变参数


代码如下:

方法一:


#include


struct  person{

char *name;

int  age;

char score;

int  id;

};

/* 

 *int printf(const char *format, ...); 

 *依据:x86平台,函数调用时参数传递是使用堆栈来实现的 

 *目的:将所有传入的参数全部打印出来 

 */ 

int push_test(const char *format, ...)

{

char *p = (char *)&format;

int i;

struct  person per;  

char c;

double d;

printf("arg1 : %sn",format);  


    //==============

p = p + sizeof(char *);

/*指针对连续空间操作时: 1) 取值  2)移动指针*/  

i = *((int *)p);

p = p + sizeof(int);

printf("arg2 : %dn",i);   


    //==============             

/*指针对连续空间操作时: 1) 取值  2)移动指针*/    

  per = *((struct  person *)p); 

p = p + sizeof(struct person);

printf("arg3: .name = %s, .age = %d, .socre=%c  .id=%dn",

          per.name,   per.age,   per.score, per.id);   


    //==============    

/*指针对连续空间操作时: 1) 取值  2)移动指针*/

c = *((char *)p);

p = p + ((sizeof(char) + 3) & ~3);

printf("arg4: %cn",c);


    //==============    

/*指针对连续空间操作时: 1) 取值  2)移动指针*/

d = *((double *)p);

p = p + sizeof(double);

printf("arg5: %fn",d);

return 0;

}


int main(int argc,char **argv)

{

struct  person per={"www.100ask.org",10,'A',123};

printf("sizeof(char   )=%dn",sizeof(char   ));

printf("sizeof(int    )=%dn",sizeof(int    ));

printf("sizeof(char  *)=%dn",sizeof(char  *));

printf("sizeof(char **)=%dn",sizeof(char **));

printf("sizeof(struct  person)=%dn",sizeof(struct  person));

    //push_test("abcd");

    //push_test("abcd",123);  

    //push_test("abcd",123,per); 

    //push_test("abcd",123,per,'c');   

    push_test("abcd",123,per,'c',2.79);

return 0;

}


方法二:


#include


struct  person{

char *name;

int  age;

char score;

int  id;

};

/* 

 *int printf(const char *format, ...); 

 *依据:x86平台,函数调用时参数传递是使用堆栈来实现的 

 *目的:将所有传入的参数全部打印出来 

 */ 

int push_test(const char *format, ...)

{

char *p = (char *)&format;

int i;

struct  person per;  

char c;

double d;

printf("arg1 : %sn",format);  


    //==============

/*指针对连续空间操作时: 1) 取值  2)移动指针*/  

p = p + sizeof(char *);

i = *((int *)p);

printf("arg2 : %dn",i);   


    //==============             

/*指针对连续空间操作时: 1) 取值  2)移动指针*/    

p = p + sizeof(int);  

per = *((struct  person *)p);  

printf("arg3: .name = %s, .age = %d, .socre=%c  .id=%dn",

          per.name,   per.age,   per.score, per.id);   


    //==============    

/*指针对连续空间操作时: 1) 取值  2)移动指针*/

p = p + sizeof(struct person);

c = *((char *)p);

printf("arg4: %cn",c);


    //==============    

/*指针对连续空间操作时: 1) 取值  2)移动指针*/

p = p + ((sizeof(char) + 3) & ~3);

d = *((double *)p);

printf("arg5: %fn",d);

return 0;

}


int main(int argc,char **argv)

{

struct  person per={"www.100ask.org",10,'A',123};

printf("sizeof(char   )=%dn",sizeof(char   ));

printf("sizeof(int    )=%dn",sizeof(int    ));

printf("sizeof(char  *)=%dn",sizeof(char  *));

printf("sizeof(char **)=%dn",sizeof(char **));

printf("sizeof(struct  person)=%dn",sizeof(struct  person));

    //push_test("abcd");

    //push_test("abcd",123);  

    //push_test("abcd",123,per); 

    //push_test("abcd",123,per,'c');   

    push_test("abcd",123,per,'c',2.79);

return 0;

}


方法三:调用库文件(stdarg.h)

代码如下:


#include

#include


struct  person{

char *name;

int  age;

char score;

int  id;

};

/* 

 *int printf(const char *format, ...); 

 *依据:x86平台,函数调用时参数传递是使用堆栈来实现的 

 *目的:将所有传入的参数全部打印出来 

 */ 

int push_test(const char *format, ...)

{

//char *p = (char *)&format;

int i;

struct  person per;  

char c;

double d;

va_list p;

printf("arg1 : %sn",format);  


    //==============

//p = p + sizeof(char *);

va_start(p, format );   

/*指针对连续空间操作时: 1) 取值  2)移动指针*/  

//i = *((int *)p);

//p = p + sizeof(int);

i = va_arg(p,int);

printf("arg2 : %dn",i);   


    //==============             

/*指针对连续空间操作时: 1) 取值  2)移动指针*/    

  //per = *((struct  person *)p); 

//p = p + sizeof(struct person);

per = va_arg(p,struct person);

printf("arg3: .name = %s, .age = %d, .socre=%c  .id=%dn",

          per.name,   per.age,   per.score, per.id);   


    //==============    

/*指针对连续空间操作时: 1) 取值  2)移动指针*/

//c = *((char *)p);

//p = p + ((sizeof(char) + 3) & ~3);

c = va_arg(p,int);

printf("arg4: %cn",c);


    //==============    

/*指针对连续空间操作时: 1) 取值  2)移动指针*/

//d = *((double *)p);

//p = p + sizeof(double);

d = va_arg(p,double);

/*避免"野指针"*/

//p = (char *)0;

va_end( p ); 

printf("arg5: %fn",d);

return 0;

}


int main(int argc,char **argv)

{

struct  person per={"www.100ask.org",10,'A',123};

printf("sizeof(char   )=%dn",sizeof(char   ));

printf("sizeof(int    )=%dn",sizeof(int    ));

printf("sizeof(char  *)=%dn",sizeof(char  *));

printf("sizeof(char **)=%dn",sizeof(char **));

printf("sizeof(struct  person)=%dn",sizeof(struct  person));

    //push_test("abcd");

    //push_test("abcd",123);  

    //push_test("abcd",123,per); 

    //push_test("abcd",123,per,'c');   

    push_test("abcd",123,per,'c',2.79);

return 0;

}


stdarg.h中


typedef char *  va_list;

#define _INTSIZEOF(n)   ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )


#define va_start(ap,v)  ( ap = (va_list)&v + _INTSIZEOF(v) )

//#define va_arg(ap,t)    ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )

//#define va_arg(ap,t)    (ap = ap + _INTSIZEOF(t), *(t *)(ap - _INTSIZEOF(t)))

#define va_arg(ap,t)    (*(t *)(ap = ap + _INTSIZEOF(t), ap - _INTSIZEOF(t)))

#define va_end(ap)      ( ap = (va_list)0 )

推荐阅读

史海拾趣

FOTEK公司的发展小趣事

进入21世纪,福禄克通过一系列精明的并购活动,实现了业务的快速扩张。2000年,公司成功收购了Wavetek Wandell Goltermann的精密测量部门,这次并购不仅增强了福禄克在电气校准市场的竞争力,还为其带来了丰富的技术专利和客户资源。此后,福禄克继续通过并购方式,进入新的技术领域和市场领域,不断拓宽其业务范围。

DURACELL公司的发展小趣事

1920年,一位年轻而聪明的科学家山谬·鲁本(Samuel Ruben)和另一位年轻而富有的钨丝电线制造商菲立普·马洛里(Philip Rogers Mallory)在一次偶然的机会中相遇。鲁本到马洛里公司寻找实验设备,两人在交谈中共同意识到将发明天赋和制造力量结合起来的巨大机会。这个巧合开启了他们的合作之旅,最终导致了金霸电池的诞生。鲁本的发明为当时的电池科技带来了革命性的改变,奠定了DURACELL公司坚实的基础。

EMS GmbH公司的发展小趣事

为了进一步提升公司的规模和实力,EMS GmbH公司积极寻求并购和资源整合的机会。通过并购其他具有技术优势和市场资源的公司,EMS GmbH公司能够快速扩大生产规模、提升技术水平和市场份额。同时,公司还注重与被并购公司的资源整合和协同发展,以实现双方的优势互补和互利共赢。这些并购和资源整合的举措使EMS GmbH公司在电子行业中的竞争地位得到了进一步巩固和提升。

请注意,以上故事仅为框架性描述,并未包含具体的细节和数据。在实际撰写时,您可以根据具体情况进行补充和完善。

维峰电子(WCON)公司的发展小趣事

质量是企业的生命线。维峰电子始终将质量管理作为公司发展的重中之重。公司建立了完善的质量管理体系,从原材料采购、生产过程到产品检验等各个环节都进行严格把控。同时,公司还引入了先进的检测设备和技术,确保产品的质量和性能达到最高标准。这些措施的实施不仅提升了产品的竞争力,也赢得了客户的信任和好评。

Green Power Solutions公司的发展小趣事
找到需要更换的电子管,并按照说明书或电路图上的标识进行拆卸。注意记录每个电子管的位置和连接方式,以便后续安装。
EXXELIA Group公司的发展小趣事
可能是由于取样电路、放大电路或磁放大器故障导致。

问答坊 | AI 解惑

C8051F+OLED+SHT21设计原理图(第二稿),欢迎大家提出宝贵意见

花了几天时间,总算把本次设计的原理图初稿完成了一下,希望关注的朋友们提点意见以助修改。 目前情况是这样的,本设计,我和空灵准备做一个更趋向于产品的小东西,所以可以做得小巧细致。目前方案如下: 1,锂电池组供电,USB通讯供电(目前锂电 ...…

查看全部问答>

这是什么结构体语法?

static struct file_operations qq2440_leds_fops = {         .owner        =        THIS_MODULE,         .ioctl        =  &nb ...…

查看全部问答>

华为3G模块问题,USTS 00 00 01 c0 canceled ,USTS 04 00 01 c0 stall pid

问题描述 :    使用华为的WCDMA 3G模块,自己做一个拨号软件,发现连接和断开有问题,有时候连了很久连不上去,有时候连上了断不开,开始时怀疑我的程序有问题,后面再windows下控制面板->网络连接里面 新建一个连接,然后一直连接, ...…

查看全部问答>

S3C2440中的Uart串口地址问题

请教S3C2440中的Uart串口地址问题:UART0的发送缓冲区地址为0X50000020,接收缓冲区地址为0X50000024,中间只相差4个字节,怎么来的64字节的FIFO缓冲区呢? 谢谢!…

查看全部问答>

COM口资源释放

我在做一个拨号程序,在进行长时间拨号后(同时做数据业务),发现拨号不成功,返回的错误码是COM口被其他程序占用了, 但是这个时候没有其他程序占用COM口,拨号也已经挂断, 我用超级终端打开后发现可以打开COM口, 但是COM口对操作没有任何反应 ...…

查看全部问答>

SYRIS.DLL

谁有SYRIS.DLL动态库的说明啊?给小弟好不好?救命啊!!!!!!!…

查看全部问答>

国内电子书企业 升级还是“等死”

本帖最后由 jameswangsynnex 于 2015-3-3 19:59 编辑 中国互联网巨头盛大推出的电子书内测价格让整个电子阅读器产业感到了前所未有的“寒意”,而友达大规模进军电子书屏幕市场使得电子书屏幕一直被一家企业垄断的格局即将被打破,加上其他企业也 ...…

查看全部问答>

大侠们,救命啊,小弟有关于dsp的问题,请大家解答

小弟最近在做dsp5509向sd卡写入速度的测试实验,可是实验结果相当的不理想,要么是写的数据不完整,要么是写入速度太慢了,用的芯片是5509.有没有哪位大侠做过相关这方面的测试,能和小弟交流下么qq:106703178email:lovejy984@163.com不胜感激啊 ...…

查看全部问答>

高端指纹锁能否促进门禁系统发展

  指纹锁作为门禁识别的衍生产品,依赖于生物识别的技术发展,国外已经逐步兴起进入更多的家庭当中。对于我们国内市场而言,指纹锁的普及率远不及它的名声那样红火。然而对于安防市场,指纹锁仍有可爆发的市场潜力,随着科技的不断进步,高端指纹 ...…

查看全部问答>

关于1117-2.5V

上面输出的是2.2V到2.3V,是给Altera FPGAEP4CE22F17C8的 2.5V管脚供电的,这个可以吗? FPGA会不会无法工作…

查看全部问答>