极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 39523|回复: 28

请教下C语言里的字符比较

[复制链接]
发表于 2017-8-11 05:33:20 | 显示全部楼层 |阅读模式
本帖最后由 Stormer 于 2017-8-11 05:35 编辑

程序中有个全局变量

char cResult = "";   //按理说赋值为空字符的时候应该写一对单引号,但是我写单引号编译提示这行出错,只好改写双引号。

void loop()中,会不停的读取网络请求获取到的字符内容

  1. cResult = client.read();

  2.     if ( strcmp(cResult , '\n') == 0 )
  3.     {......}
复制代码


我想判断从client.read()读取的字符是否为换行符。这段代码编译通过、运行正常,但是ARDUINO IDE显示一堆警告:

  1. Users/starock/Desktop/WebClientRepeating/WebClientRepeating.ino:33:16: warning: invalid conversion from 'const char*' to 'char' [-fpermissive]
  2. char cResult = "";
  3.                 ^
  4. /Users/starock/Desktop/WebClientRepeating/WebClientRepeating.ino: In function 'void loop()':
  5. /Users/starock/Desktop/WebClientRepeating/WebClientRepeating.ino:70:31: warning: invalid conversion from 'char' to 'const char*' [-fpermissive]
  6.      if ( strcmp(cResult , '\n') == 0 )
  7.                                ^
  8. In file included from /Applications/Arduino.app/Contents/Java/hardware/arduino/avr/cores/arduino/Arduino.h:25:0,
  9.                  from sketch/WebClientRepeating.ino.cpp:1:
  10. /Applications/Arduino.app/Contents/Java/hardware/tools/avr/avr/include/string.h:287:12: note: initializing argument 1 of 'int strcmp(const char*, const char*)'
  11. extern int strcmp(const char *, const char *) __ATTR_PURE__;
  12.             ^
  13. /Users/starock/Desktop/WebClientRepeating/WebClientRepeating.ino:70:31: warning: invalid conversion from 'char' to 'const char*' [-fpermissive]
  14.      if ( strcmp(cResult , '\n') == 0 )
  15.                                ^
  16. In file included from /Applications/Arduino.app/Contents/Java/hardware/arduino/avr/cores/arduino/Arduino.h:25:0,
  17.                  from sketch/WebClientRepeating.ino.cpp:1:
  18. /Applications/Arduino.app/Contents/Java/hardware/tools/avr/avr/include/string.h:287:12: note: initializing argument 2 of 'int strcmp(const char*, const char*)'
  19. extern int strcmp(const char *, const char *) __ATTR_PURE__;
  20.             ^
  21. Sketch uses 9504 bytes (29%) of program storage space. Maximum is 32256 bytes.
  22. Global variables use 601 bytes (29%) of dynamic memory, leaving 1447 bytes for local variables. Maximum is 2048 bytes.
复制代码



请问应该怎么修改才能解决这些警告呢?




回复

使用道具 举报

发表于 2017-8-11 09:58:44 | 显示全部楼层
本帖最后由 Super169 于 2017-8-11 10:00 编辑
Stormer 发表于 2017-8-11 09:38
单引号的话需要加个空格? 双引号的话,cResult变成一个指向空字符串的指针?

啊,10几年不用C了,(* ...


對, 如果用單引, 中間要加上 空格, 把 0x20 填到 cResult 去.  當然, 也可以直接  = 0; 作為 initial value, 看實際需要吧.

如果用 雙引, 就是一個 const char*, 不肯定會怎樣轉換:
(1) char*  指向的字串中的第一個 byte?  
(2) char* 的地址的第一個 byte?  

結果有點不清楚.  所以, 出現錯誤可能更加合理.
回复 支持 1 反对 0

使用道具 举报

发表于 2017-8-11 09:31:11 | 显示全部楼层
明白原因, 比知道答案更加重要呢.

你先要知道 char cResult = '';   (單引號)  為什麼會有問題吧.
自己想想, 這句指令, 會把什麼放到 cResult 去?   明白之後, 應該知道要怎樣改吧.

另外, 也不妨想想 '' 跟 "" 有什麼分別, char cResult = "";  會是什麼意思.
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-8-11 09:38:03 | 显示全部楼层
Super169 发表于 2017-8-11 09:31
明白原因, 比知道答案更加重要呢.

你先要知道 char cResult = '';   (單引號)  為什麼會有問題吧.

单引号的话需要加个空格? 双引号的话,cResult变成一个指向空字符串的指针?

啊,10几年不用C了,(*/ω╲*)全忘光了。
回复 支持 反对

使用道具 举报

发表于 2017-8-11 10:01:55 | 显示全部楼层
補充, 在比較的時候, cResult 是 char, 直接用  if (cResult == '\n') 就可以了.
回复 支持 反对

使用道具 举报

发表于 2017-8-11 10:20:48 | 显示全部楼层
为啥不直接比较,cResult == '/n'
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-8-11 15:36:19 | 显示全部楼层
通幽境 发表于 2017-8-11 10:20
为啥不直接比较,cResult == '/n'

第一开始就是这样比较的,但是可能是初始化写错了所以编译的时候这样==也报错。 谢谢各位!
回复 支持 反对

使用道具 举报

发表于 2017-8-12 23:39:19 | 显示全部楼层
大概整理一下思路:
char cResult="";//这个不报错。那么回想一下,表示字符串的结尾标志 是 \0 对吧
那么
char cResult="";//其实类似于 char cResult=0;
之所以说是类似 是因为用到了双引号""  那么实际上就是字符数组(字符数组的名字就是指针)
所以char cResult=""; 其实就应该是char cResult[1]=0;//也就是说 cResult是一个数组大小为1的char数组(数组大小为1的char数组 虽然和char一样 都是含有一个字符 但是要看成不一样的)
那么报错的原因就是:
strcmp()这个函数有两个参数 这两个参数按道理应该是两个字符串 也就是char* char[20] 这种的
但是呢 楼主在调用的时候 是这么写的
strcmp(cResult,'\n')//cResult 在声明的时候虽然是char类型的,但是赋值的时候用到了双引号 所以自动变成char* 类型的了,第一个参数没问题
第二个参数是'\n' 单引号了 那就是char类型的了 这个参数是有点小小问题的(之所以说是小小问题 是因为编译器给出的是警告 而不是错误)
有好心的人给楼主提示 为什么不直接比较 cResult=='\n'
楼主说:这样会报错
这个问题还是出现在cResult在声明并赋值的那里 因为用到了双引号"" 所以自动变成了char*类型的
而char*类型的 是不能直接用==比较的
问题的解决方法就是:
在声明char类型变量的时候 不用给他赋值 直接声明 char cResult;
反正这个变量是用来接收结果的
回复 支持 反对

使用道具 举报

发表于 2017-8-13 02:50:30 | 显示全部楼层
qq576193486 发表于 2017-8-12 23:39
大概整理一下思路:
char cResult="";//这个不报错。那么回想一下,表示字符串的结尾标志 是 \0 对吧
那 ...

我在第一次回帖就說了: 明白原因, 比知道答案更加重要呢.

你的整理, 比樓主的更混亂.  只是在知道結果後, 胡亂堆砌原因.  

char cResult = "";  為什麼一定是 0?  

不要自己胡亂假設,  "="  的功能, 是要看語言本身的設定.  
(char) = (const char*) 的結果, 沒有設定就是沒有設定, 不可以自已亂說的, 特別是 c 的指針.   
在 c 語言上, 從來不會有這種替代的.  
(const char *) 是一個地址, 直接的 "=", 就是成立的話, 也只會把地址的數值填進去.

  
所以char cResult=""; 其实就应该是char cResult[1]=0;


這更加是完全是亂來的.   還是先了解一下 char 跟 char* 的分別 比較好.

如果對 (const char *) 放進 char 的問題, 還是不明白, 可以嘗試一下  (char *) 放到 char 會有什麼後果.
是否會把 (char *)[0] 放進去?  再想想是把什麼放了進去吧.
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-8-13 06:39:45 | 显示全部楼层
等下次再用ARDUINO写东西的时候,我好好复习总结一下字符,字符串,字符数组和指针。 一直都用C#之类的人都傻了从来不操心这些。
回复 支持 反对

使用道具 举报

发表于 2017-8-13 12:06:08 | 显示全部楼层
Super169 发表于 2017-8-13 02:50
我在第一次回帖就說了: 明白原因, 比知道答案更加重要呢.

你的整理, 比樓主的更混亂.  只是在知道結果 ...

Arduino 的IDE虽然是用JAVA开发的,但是烧写的程序是用类C的语言。那么一个字符串的结尾就是要补上\0的
查一下MSDN 也就知道\0就是0啊
"" 这样的字符串 那么就是\0
char cResult="" 就变成了char 指针变量了
cResult就是指针 指针当然不可能是0 我说的是指针变量是0
回复 支持 反对

使用道具 举报

发表于 2017-8-13 18:08:49 | 显示全部楼层
qq576193486 发表于 2017-8-13 12:06
Arduino 的IDE虽然是用JAVA开发的,但是烧写的程序是用类C的语言。那么一个字符串的结尾就是要补上\0的
...

你想說的是 zero terminate 既意思, 對嗎? 這些基本東西, 不需要查 MSDN 了.  
你好像還沒看到問題所在, 只是把它胡亂套進來.

char 就是 char, (char *)  就是 (char *)

char cResult="" 就变成了char 指针变量了

你知道自己在說什麼嗎?

如果你還是要這樣想, 我也無話可說了.  你有你的自由, 就用你的想法去做好了, 請恕小弟多事了.
回复 支持 反对

使用道具 举报

发表于 2017-8-13 23:55:56 | 显示全部楼层
Super169 发表于 2017-8-13 18:08
你想說的是 zero terminate 既意思, 對嗎? 這些基本東西, 不需要查 MSDN 了.  
你好像還沒看到問題所在, ...

虽然它一开始写的是char cResult
但是它后面又用了cResult="" 这里就强制改变了变量类型
回复 支持 反对

使用道具 举报

发表于 2017-8-14 10:47:22 | 显示全部楼层
qq576193486 发表于 2017-8-13 23:55
虽然它一开始写的是char cResult
但是它后面又用了cResult="" 这里就强制改变了变量类型

本來不想再說了, 但看到你又胡扯到 "强制改变了变量类型", 想你應該是初學的吧, 不希望你把錯誤的訊息誤導了別人.

看來你是對 implicit type conversion 有點誤解了.

當 A = B 時, 如果 A 跟 B 是不同類的話, 確實是會嘗試進行轉換.
但並不是把  A 改變, 而是嘗試把 B 轉成 A 的類, 再送進 A.  
嚴格來說, 只是把 B 的值抄出檬, 作中途轉換, B 還是不變的.
完成之後, A 跟 B 的性質是沒有改變的.


char cResult = "";

就會看成是 char = (const char*), 就是要進行轉換, 也只會是把後面的 (const char*) 先轉成 char 再放進去.

就等同於:

char cResult = (char) "";

如果你想說把地址放進去的話, 也要考慮一下儲放空間的大小.

用 int = (char *) , 還可以說得通, 而且也是合理的用.  
但 char = (char *), 就怎樣胡扯也不行了.  難道要說是把半個地址給記下來?

當然, 它亦不會自動變成:

char cResult = ""[0] ;


不要太多的胡亂猜想了, 實際去測試一下就更清楚.

如果你真的有試過, 可以把 char 強制變成 char* 的話, 我也想見識一下, 希望你可以把測試的源碼分享出來, 讓大家學習學習.
回复 支持 反对

使用道具 举报

发表于 2017-8-15 00:09:10 | 显示全部楼层
Super169 发表于 2017-8-14 10:47
本來不想再說了, 但看到你又胡扯到 "强制改变了变量类型", 想你應該是初學的吧, 不希望你把錯誤的訊息誤 ...

..............

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-3-29 02:16 , Processed in 0.043972 second(s), 22 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表