打印
[嵌入式linux]

串口源代码为什么要用vsprintf(string,fmt,ap);这个函数?

[复制链接]
3469|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
子玥|  楼主 | 2014-5-7 15:49 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
msblast| | 2014-5-7 16:12 | 只看该作者
如果不用vsprintf(string,fmt,ap);
string就是一个未初始化的数组,那么调用Uart_SendString(string);不但不能送出预期的字符串,而且很危险。
vsprintf(string,fmt,ap);的作用就是将格式化的字符串存储到string。

使用特权

评论回复
板凳
子玥|  楼主 | 2014-5-7 16:50 | 只看该作者
msblast 发表于 2014-5-7 16:12
如果不用vsprintf(string,fmt,ap);
string就是一个未初始化的数组,那么调用Uart_SendString(string);不但 ...

Uart_SendString( char *s[])
{
   char **p;
   int i;
   p=s;
   for(i=0;i<256;i++)
   Uart_SendByte(*p++);
}
就这样简单的形式不可以发送么?
不明白您说的string是一个未初始化的数组是什么意思?请您再详细说一下好么?

使用特权

评论回复
地板
msblast| | 2014-5-7 17:16 | 只看该作者
子玥 发表于 2014-5-7 16:50
Uart_SendString( char *s[])
{
   char **p;

给你搞复杂了,我修改如下
void Uart_SendString( char *s)
{
   int i;
   for(i=0;i<256;i++)
     Uart_SendByte(*(s+i));
}
这样写有越界的危险。

回到前面的问题
在函数里的局部变量的存储空间是栈空间,如果不进行初始化,它的值是随机的。

使用特权

评论回复
5
子玥|  楼主 | 2014-5-8 10:20 | 只看该作者
本帖最后由 子玥 于 2014-5-8 17:02 编辑
msblast 发表于 2014-5-7 17:16
给你搞复杂了,我修改如下
void Uart_SendString( char *s)
{

不好意思,我初学,可能问题很弱智,请见谅。
  va_list ap;
char string[256];
在这个函数里不也定义了string数组的大小么,为什么这个没有,那个简单的程序就有越界的危险?
调用函数的时候,本身不是已经给string这个数组赋值了,还是不明白初始化这个问题。
如果您方便的话可以加我一下QQ么,我想把这个问题搞明白,谢谢。

使用特权

评论回复
6
yimaoqian01| | 2014-5-8 10:38 | 只看该作者
爷关天像,发现我也不会哎,。

使用特权

评论回复
7
msblast| | 2014-5-8 11:57 | 只看该作者
子玥 发表于 2014-5-8 10:20
不好意思,我初学,可能问题很弱智,请见谅。
  va_list ap;
char string[256];

如果vsprintf(string,fmt,ap);生成的字符串长度大于等于256,也会越界。如果非要这么写,有一点应该确定,那就是整个字符串的长度小于256

char string[256];数组未初始化
char string[256] = {0};整个数组初始化为0
char string[256] = {'A','B','C',};前面三个初始化为 A B C,其余为0

使用特权

评论回复
8
子玥|  楼主 | 2014-5-8 15:41 | 只看该作者
msblast 发表于 2014-5-8 11:57
如果vsprintf(string,fmt,ap);生成的字符串长度大于等于256,也会越界。如果非要这么写,有一点应该确定 ...

调用函数的时候比如Uart_SendString("hello\n");
hello 不是已经赋值给数组了么?这不叫初始化么

使用特权

评论回复
9
msblast| | 2014-5-8 15:53 | 只看该作者
子玥 发表于 2014-5-8 15:41
调用函数的时候比如Uart_SendString("hello\n");
hello 不是已经赋值给数组了么?这不叫初始化么 ...

那么"hello\n"赋值给了哪个数组?

使用特权

评论回复
10
子玥|  楼主 | 2014-5-8 16:20 | 只看该作者
msblast 发表于 2014-5-8 15:53
那么"hello\n"赋值给了哪个数组?

Uart_SendString( char *s[])
{
   char **p;
   int i;
   p=s;
   for(i=0;i<256;i++)
   Uart_SendByte(*p++);
}
不是定义了 char *s[] 这个数组么?

使用特权

评论回复
11
msblast| | 2014-5-8 16:23 | 只看该作者
本帖最后由 msblast 于 2014-5-8 16:27 编辑

char *s[]和"hello\n"类型不匹配的
我们不在同一个频道上对话呀

使用特权

评论回复
12
子玥|  楼主 | 2014-5-8 16:29 | 只看该作者
msblast 发表于 2014-5-8 16:23
char *s[]和"hello\n"类型不匹配的
我们不在同一个频道上对话呀

不好意思,因为我不懂,所以。。。。。。

使用特权

评论回复
13
msblast| | 2014-5-8 17:08 | 只看该作者
子玥 发表于 2014-5-8 16:29
不好意思,因为我不懂,所以。。。。。。

今天讨论的内容有点多且杂,总结有那么几点
1、函数的可变参数
2、函数的形参和实参
3、指针以及指向指针的指针
4、局部变量的存储空间及堆栈空间
5、变量以及数组的初始化
6、数组越界

先把这些内容熟悉了吧

使用特权

评论回复
14
and| | 2014-5-11 15:10 | 只看该作者
Uart_SendString ("time is %d %d %d\n", year, month, day);
楼主你的Uart_SendString能这样做吗?

但是1楼的代码就可以。

使用特权

评论回复
15
zero_007| | 2014-5-16 18:01 | 只看该作者
这是为了格式化输出可变参数。 如果单纯的用uartsend(str),它是不会输出你想要的结果的。

使用特权

评论回复
16
zhangdelai2012| | 2015-6-16 18:45 | 只看该作者
本帖最后由 zhangdelai2012 于 2015-6-17 15:43 编辑

其实并不是楼上那些人说的那样。其实主要为了打印比如带参数的打印信息,如果没有vsprintf的话,你需要自己去实现这个函数的功能。
为了方便就直接用开发工具自带的函数了。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

7

帖子

0

粉丝