打印

顶山**!顶鹰!我用技术贴来结贴吧

[复制链接]
6379|41
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
冷漠|  楼主 | 2009-6-3 11:01 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
有一组字符串"Hello World",欲通过51串口发送。

假设定义字符串 char  a[]="Hello World";

咱天下第一老所长写的发送循环入口条件是:

for( i=0; i<sizeof(a); i++ )

有问题吗?

俺告诉他:这是字符串,自己有指针和边界'\0';不是数组概念。无需求长度sizeof(a)。

所以循环条件应为:

for ( ; *a!='\0'; )

两者结果一样吗?——不一样!差了一个字符串结尾字节0x00!

如若2种写法最终效果一样,也就没什么可较真的了。可惜老所长发送的是'Hello World\0'多发送了一字节'\0'! 还要作为“完美”范本推荐给大家。

老所长振振有词:“只要传入一个buffer, 一定要同时规定size, 这是菜鸟与高手的区别之一。”(把字符串当做数组一样处理大概就是高手的境界了。)

别人谈的是C语言字符串类型,他却在这牛头不对马嘴地讲起了数组概念,就像以往C混不过去,就来C++,C++再混不过去,他给你来C#,他总是有理。
   顾左右而言它,——这大概也是强词夺理的手法之一?

提醒一句:如若 a字符串是一个协议帧,您老大人多发送了一个字节,就意味着接收方接收到的是错误信息帧,CRC帧校验通不过而被废弃掉。
如若a字符串是一个密码组,多输入一位....
如若a字符串是一条命令,....航天器就掉下来啦。


C语言字符串基础 (——摘自任何C语言教材)
   字符串是一种重要的数据类型。......字符串就是一串零个或多个字符,并且以一个位模式为全0的NUL字节结尾。因此,字符串所包含的字符内部不能出现NUL字节。这个限制很少会引起问题,因为NUL字节并不存在与它关联的可打印字符,这也是它被选为终止符的原因。NUL字节是字符串的终止符,但它本身并不是字符串的一部分,所以字符串的长度并不包括NUL字节。

   强调一下最后一句:“NUL字节是字符串的终止符,但它本身并不是字符串的一部分,所以字符串的长度并不包括NUL字节。”
   
   哈哈,老爷子把字符串当作一般数组一样求sizeof(a),结果把字符串终止符NUL也算了进去,比实际字符串长度多算了一字节! 还因此极力向菜鸟推荐:今后凡遇到发送字符串均视为数组发送一样处理,均以我“天下第一”的通用发送程序为标准。

   什么?多发送了一字节'\0'?  咳,那正是俺天下第一的创新发明,其中深奥说了你们也不懂,无可奉告。那是为了避免攻击。

   结论:1、求一个字符串(数组)的长度,应该用strlen( ),而不是sizeof( )。——字符串不是数组。
         2、如若修炼了几十年还搞不清楚这类问题,请尽可能使用丰富的C处理字符串和字符的库函数。这对C++,C#,JAVA...都是一样的。

(高手说:“我写C程序从来不用库函数。...”结果就是,错误程序放在那里N天,自己还不知道。还在“以完美的心情欣赏它。”)
特别是,还暴跳如雷地训导学生“菜鸟”。这恐怕就是高手和菜鸟的根本区别了。


下面验证程序:

#include<stdio.h>
#include<string.h>

code char a[]="Hello World";


void main()
{
char cc,ss;

 cc=sizeof(a);
 ss=strlen(a);

printf(" %bd  %bd",cc,ss);

while(1);
}

  打印结果:12  11
 
   关于这个程序验证的结论,不知道天下第一高手,老所长还有什么牛头不对马嘴的“总是有理”的理由可以向大家辩解的。

   别在这谈数组。这讨论的是字符串类型。

相关帖子

沙发
gaohq| | 2009-6-3 11:12 | 只看该作者

顺便问一下,如下问题。

uchar i=0;
while(str!='/0')
{
 writ_LCD_1602(str);
 i++;
}


uchar i;
for(i=0;str)!='/0';i++)
  writ_LCD_1602(str);

结果就是不一样,不解?????

使用特权

评论回复
板凳
冷漠|  楼主 | 2009-6-3 11:14 | 只看该作者

回LS,'\0' 不是笔误吧?

'\0'或者NUL。

使用特权

评论回复
地板
zyboy| | 2009-6-3 11:29 | 只看该作者

不是数组和字符串的问题,是程序要严谨

程序要考虑到各种异常情况,万一传入的是数组怎么办,你根本无法保证传入的数组还是字符串,C没有严格意义的字符串类型(个人看法),正因为这一点,所以对它的处理要加倍小心。程序还是严谨的好。比如一个程序明明知道只会传0,1两个变量,但还是对其他情况预防,这是一个好习惯。

a[3]={'1','2','0'};  //字符数组
a[3]={'1','2',0};    //字符串 哈哈,一下就由字符数组变成字符串了

如果程序员一不小心写错了,你的程序如果做了预防处理,可很快定位错误,否则,你自己到代码大海里去找问题吧!

使用特权

评论回复
5
highgear| | 2009-6-3 11:39 | 只看该作者

冷嬷嬷, 不愧是东厂太监。

我懒得去辩解冷嬷嬷的谎言,造谣啊诬蔑,那是太监行为。
我说过:你不服,可以pk。我最后的帖子又让冷嬷嬷傻眼了,是吧?敢情别人的字符串根本没有 "\0". 


http://www.21icbbs.com/club/bbs/list.asp?Page=1&boardid=11&t=3347188&p=3&tp=%BC%B1%B0%A1%A3%A1%B5%A5%C6%AC%BB%FA%B4%AE%BF%DA%CD%A8%D0%C5%B3%CC%D0%F2%CE%CA%CC%E2%A3%A1%286%2E2%B8%FC%D0%C2%29

highgear 发表于 2009-6-3 09:34 侃单片机 ←返回版面    

42楼: 冷嬷嬷啊,你看清楚了 

搂主的定义:
uchar a[3]={'C','I','S'};
uchar b[5]={'S','K','5','3','0'};
uchar c[6]={'F','D','5','0','0','0'};
uchar d[2]={'T','W'};

另外:我给出的是一个通用程序,不管字符还是binary 数组。一个根本不了解'\0' 后果的刘公公的“改动“实在是胡扯,至少搂主的这种定义就会产生问题。
f(char* buffer, int size) 这种做法,就是防备像搂主这样的程序员。

使用特权

评论回复
6
john_light| | 2009-6-3 12:00 | 只看该作者

码字我不在行

只好路过并围观了。

使用特权

评论回复
7
taoest| | 2009-6-3 12:00 | 只看该作者

char a[]='Hello World';

这里确实没有结束符\0,因为用的是单引号。如果用双引号才会有\0。

使用特权

评论回复
8
zyboy| | 2009-6-3 12:04 | 只看该作者

吃饭了,吃饭了,半天又混过去了,

吃饭了,吃饭了,半天又混过去了,哈哈

使用特权

评论回复
9
冷漠|  楼主 | 2009-6-3 12:59 | 只看该作者

7楼细心。经提醒LZ已经修改过来了。谢谢。

字符串用单引号是语法错误。编译通不过。

所以单字符' '后面没有‘\0'。

a?:
    DB  'H' ,'e' ,'l' ,'l' ,'o' ,' ' ,'W' ,'o' ,'r' ,'l' 
    DB  'd' ,000H

这是字符串定义char a[ ]="Hello World";编译结果,后面 000H 是编译器自动加的。

当然如果定义为:

code char a[]={'H' ,'e' ,'l' ,'l' ,'o' ,' ' ,'W' ,'o' ,'r' ,'l' ,'d' };

就是真的数组了。
    RSEG  ?CO?STRING1

a?:
    DB    048H
    DB    065H
    DB    06CH
    DB    06CH
    DB    06FH
    DB    020H
    DB    057H
    DB    06FH
    DB    072H
    DB    06CH
    DB    064H

使用特权

评论回复
10
gaohq| | 2009-6-3 13:46 | 只看该作者

回楼主

'/0'是笔误,实际是'\0'
我开始模仿别人的写法用
uchar i=0;
while(str!='\0')
{
writ_LCD_1602(str);
i++;
}
是可以,后来我想按自己的思路改成如下

uchar i;
for(i=0;str)!='\0';i++)
  writ_LCD_1602(str);
就不行了,困惑了好久就放弃了,

使用特权

评论回复
11
冷漠|  楼主 | 2009-6-3 13:56 | 只看该作者

5楼老所长原来是为LZ那段程序写的发送?实在对不起,....

那意思就是说,“我没有当做是字符串。我是针对LZ的程序改进的。”呵呵,且看自己贴的程序:

uchar a[3]={'C','I','S'};
uchar b[5]={'S','K','5','3','0'};
uchar c[6]={'F','D','5','0','0','0'};
uchar d[2]={'T','W'};

这上面的数组长度可是清清楚楚告诉你了,那您sizeof()什么哪?噢,既通用于字符串,又专用于数组。老爷子果然厉害,sizeof()和strlen()2者通用,比Kenneth和中外教授厉害多了,就是不稀罕写出自己怎么PK中外教授的:也只能在21IC论坛这充大堂主,反正这也没有比您水平高的。您都50多岁啦,怎么还跟我们小屁孩一块混。准备混一辈子?这么高水平成天为上面的程序解惑?这天下第一也太浪费了吧。

还不如给我们公司解决点实际问题,至少银子可观呀。可惜,问什么不知道什么,不问的全都知道。也就只能为uchar a[3]={'C','I','S'};这样类似的问题排忧解惑?再复杂点的问题上不去了?


俺一直注意的是LZ的直接问题:

在此先感谢大家帮助,感谢大家的积极关注!
现在将原来的程序彻底推翻,重新进行编写,已经在实验板上测试成功。但还有以下几个问题:
1:输出的问题
   目前的输出是:
   TW GX45 MA200000 L000000000  BV40 CIS SK530 FD5000
   而我想要的结果是:
   CIS SK530 FD5000 TW GX45 MA200000 L000000000  BV40。
   但在复位后是可以的,即输出“CIS SK530 FD5000 TW GX45        MA200000 L000000000  BV40。”//

LZ想要的结果是:
   CIS SK530 FD5000 TW GX45 MA200000 L000000000  BV40。

天下第一高手教别人uchar a[3]={'C','I','S'};分段写?小心被zyboy 杀了。


zyboy 发表于 2009-5-30 15:25 侃单片机 ←返回版面    

5楼: 程序写的真的。。。。有种想杀你的冲动 

程序写的真的。。。。有种想杀你的冲动!

使用特权

评论回复
12
冷漠|  楼主 | 2009-6-3 14:14 | 只看该作者

回10楼,等我。

uchar i;
for(i=0;str)!='\0';i++)
  writ_LCD_1602(str);

写得太棒了。我去试试。

使用特权

评论回复
13
dld2| | 2009-6-3 14:37 | 只看该作者

C语言有“字符串”这种数据类型吗

俺火星了。

使用特权

评论回复
14
HWM| | 2009-6-3 14:41 | 只看该作者

俺火星刚回来,来看热闹的。

使用特权

评论回复
15
McuPlayer| | 2009-6-3 14:42 | 只看该作者

纯看热闹,不看代码

使用特权

评论回复
16
耕在此行| | 2009-6-3 14:58 | 只看该作者

呵呵

 highgear 难道是换了马甲出来的?

使用特权

评论回复
17
zyboy| | 2009-6-3 16:04 | 只看该作者

打了半天口水,总结一下


C语言并不支持字符串数据类型。但是,它允许作为字符数组来表示字符串。

字符数组有两种用法:
一是当作字符的数组来使用。这时的用法与整数的数组、 实数的数组等相同,对字符数组的输入、输出、赋值、引用等都是针对单个的元素进行。
二是更为重要的用法即存储、处理字符串。这时它除了可以像普通数组一样使用外,还可以把字符串作为一个整体进行操作。

字符串两种写法
char a[]={"abc"};  //推荐
char b[]={'a','b','c',0};

由于字符串是字符数组的一种表达形式,出现非字符串数组,是无法根据类型识别的,对于字符串处理函数会产生不良后果。对于使用字符串处理函数之前,要事先做好判断,或者重写字符处理函数。

还想进来看热闹的,失望了吧,被我耍了吧,哈哈

使用特权

评论回复
18
冷漠|  楼主 | 2009-6-3 18:51 | 只看该作者

to 10楼,实验做过了,没问题。

for (  ; str)!=   ;  ) 是笔误吧。

请比较for和while两个src文件,汇编码完全一样。

使用特权

评论回复
19
ningling_21| | 2009-6-3 20:12 | 只看该作者

路过,学习经验了

使用特权

评论回复
20
lost1421| | 2009-6-3 20:50 | 只看该作者

我也路过

看看。

使用特权

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

本版积分规则

17

主题

921

帖子

4

粉丝