Arduino IDE中char类型的变量在不同开发板上的差异

    最近自己在学习用arduino IDE做一些传感器的演示程序,用的开发板最初为arduino nano,最近入手一块ESP8266的板子,打算把原来在arduino nano上运行的程序移植到ESP8266上,其中有一个程序,移植到ESP8266以后是可以运行的,但是执行结果却和在arduino nano上不一样,经过长时间的分析,发现了一个两块开发板之间关于char数据类型和负数的差异,在这里记录下来,希望遇到类似情况的朋友看到这篇文章能少走弯路。

    原始程序我简化了一下,放在下面:

switch (test(state))
{
case -1:
    dosomething1();
    break;
case 1:
    dosomething2();
    break;
case 0:
    dosomething3();
    break;
}

char test(word state)
{
    switch (state)
    {
    case NONE:
        return 0;
        break;
    case OK:
	    return 1;
        break;
    case FAIL:
        return -1;
        break;
    }
}

    总之就是switch语句后面用作判断的值是通过函数test返回的。test函数返回值的类型是char,返回三种状态,分别为“-1”、“0”、“1”。主程序用switch语句判断这3个值,分别执行不同的操作。
    在ESP8266上,程序运行以后发现test函数返回值为“-1”的时候,switch语句中判断结果为“-1”的那部分代码并没有被执行。而在arduino nano上却是正常的。
    在百度上搜索了一下char数据类型,有些页面有如下的说明:
在这里插入图片描述
在这里插入图片描述

    如果是这样的话,char类型的变量可以存放范围在-128~127之间的数值,程序应该没问题啊。
    后来我又到arduino官网找到语法的说明,官网(https://www.arduino.cc/reference/en/language/variables/data-types/char/)对char数据类型的说明是这样的:

Char
一种数据类型,占用一个字节的内存,存储一个字符值。字符文字用单引号写成:‘A’,对于多个字符,字符串使用双引号:“ABC”。
但是,字符实际上存储为数字。你可以在ASCII图表中查看特定编码。这意味着可以对使用ASCII值的字符进行算术运算。例如,‘A’+1的值为66,因为大写字母A的ASCII值为65。
例子
Char chr_a = ‘a’ ;//declaration of variable with type char and initialize it with character a
Char chr_c = 97 ;//declaration of variable with type char and initialize it with character 97

在官网上另一个页面https://www.arduino.cc/en/Reference.Char却有如下说明:

The char datatype is a signed type, meaning that it encodes numbers from -128 to 127. For an unsigned, one-byte (8 bit) data type, use the byte data type.
char数据类型是带符号的类型,这意味着它将对-128到127之间的数字进行编码。对于无符号的1字节(8位)数据类型,请使用byte数据类型。

    另外switch语句接受的变量也只是int和char两个类型。
    按照上面的说明,char类型的变量应该是可以存放-1~-128之间的负数值的,那为什么程序执行的时候就不正常呢?
    我们还是来做个测试,用事实说话,我们用下面这段测试代码,分别在两个不同的开发板上运行:

void setup() {
  char test;
  Serial.begin(115200);
  Serial.println();
  Serial.println();
  test=-1;
  switch (test) {
  case -1:
    Serial.println("The value of the variable is:-1.");
    print_char_var(test);
    break;
  case 1:
    Serial.println("The value of the variable is:1.");
    print_char_var(test);
    break;
  case 0:
    Serial.println("The value of the variable is:0.");
    print_char_var(test);
    break;
  default:
    Serial.println("The value of the variable is:-1.In switch default.");
    print_char_var(test);
    break;
  }
  //================================================
  test=0;
  switch (test) {
  case -1:
    Serial.println("The value of the variable is:-1.");
    print_char_var(test);
    break;
  case 1:
    Serial.println("The value of the variable is:1.");
    print_char_var(test);
    break;
  case 0:
    Serial.println("The value of the variable is:0.");
    print_char_var(test);
    break;
  default:
    Serial.println("The value of the variable is:0.In switch default.");
    print_char_var(test);
    break;
  }
//===========================================
  test=1;
  switch (test) {
  case -1:
    Serial.println("The value of the variable is:-1.");
    print_char_var(test);
    break;
  case 1:
    Serial.println("The value of the variable is:1.");
    print_char_var(test);
    break;
  case 0:
    Serial.println("The value of the variable is:0.");
    print_char_var(test);
    break;
  default:
    Serial.println("The value of the variable is:1.In switch default.");
    print_char_var(test);
    break;
  }
//===========================================
  test=-2;
  switch (test) {
  case -1:
    Serial.println("The value of the variable is:-1.");
    print_char_var(test);
    break;
  case 1:
    Serial.println("The value of the variable is:1.");
    print_char_var(test);
    break;
  case 0:
    Serial.println("The value of the variable is:0.");
    print_char_var(test);
    break;
  case -2:
    Serial.println("The value of the variable is:-2.");
    print_char_var(test);
    break;
  default:
    Serial.println("The value of the variable is:-2.In switch default.");
    print_char_var(test);
    break;
  }
//===========================================
  test='A';
  switch (test) {
  case -1:
    Serial.println("The value of the variable is:-1.");
    print_char_var(test);
    break;
  case 1:
    Serial.println("The value of the variable is:1.");
    print_char_var(test);
    break;
  case 0:
    Serial.println("The value of the variable is:0.");
    print_char_var(test);
    break;
  case -2:
    Serial.println("The value of the variable is:-2.");
    print_char_var(test);
    break;
  case 'A':
    Serial.println("The value of the variable is:A.");
    print_char_var(test);
    break;
  default:
    Serial.println("The value of the variable is character A.In switch default.");
    print_char_var(test);
    break;
  }
}

void loop() {
  // put your main code here, to run repeatedly:

}
void print_char_var(char charvar)
{
  Serial.print("The value of the variable is:");
  Serial.print(charvar,BIN);
  Serial.println("(BIN)");
  Serial.print("The size of the variable is:");
  Serial.println(sizeof(charvar));
  Serial.println();
}

    Arduino得到的结果如下:

08:44:04.578 -> 
08:44:04.578 -> 
08:44:04.578 -> The value of the variable is:-1.
08:44:04.578 -> The value of the variable is:11111111111111111111111111111111(BIN)
08:44:04.578 -> The size of the variable is:1
08:44:04.578 -> 
08:44:04.578 -> The value of the variable is:0.
08:44:04.578 -> The value of the variable is:0(BIN)
08:44:04.578 -> The size of the variable is:1
08:44:04.578 -> 
08:44:04.578 -> The value of the variable is:1.
08:44:04.625 -> The value of the variable is:1(BIN)
08:44:04.625 -> The size of the variable is:1
08:44:04.625 -> 
08:44:04.625 -> The value of the variable is:-2.
08:44:04.625 -> The value of the variable is:11111111111111111111111111111110(BIN)
08:44:04.625 -> The size of the variable is:1
08:44:04.625 -> 
08:44:04.625 -> The value of the variable is:A.
08:44:04.625 -> The value of the variable is:1000001(BIN)
08:44:04.625 -> The size of the variable is:1
08:44:04.625 ->

    ESP8266得到的结果如下:

08:44:02.712 ->
08:44:02.807 -> 
08:44:02.807 -> The value of the variable is:-1.In switch default.
08:44:02.807 -> The value of the variable is:11111111(BIN)
08:44:02.807 -> The size of the variable is:1
08:44:02.807 -> 
08:44:02.807 -> The value of the variable is:0.
08:44:02.807 -> The value of the variable is:0(BIN)
08:44:02.807 -> The size of the variable is:1
08:44:02.807 -> 
08:44:02.807 -> The value of the variable is:1.
08:44:02.807 -> The value of the variable is:1(BIN)
08:44:02.807 -> The size of the variable is:1
08:44:02.807 -> 
08:44:02.807 -> The value of the variable is:-2.In switch default.
08:44:02.807 -> The value of the variable is:11111110(BIN)
08:44:02.807 -> The size of the variable is:1
08:44:02.807 -> 
08:44:02.807 -> The value of the variable is:A.
08:44:02.807 -> The value of the variable is:1000001(BIN)
08:44:02.854 -> The size of the variable is:1
08:44:02.854 -> 

    从结果来看,不知道为什么,arduino nano上,给char类型的变量一个负值,arduino nano用二进制输出变量的值会看到输出的二进制是32位(4个字节)。而按官方说明,char类型的变量应该是1个字节(8位)。而且有意思的是,在switch语句进行判断的时候,仍然可以正常判断为负值。而在ESP8266上,负值倒是正常地按1个字节(8位)来存储,但是switch判断的时候是却并不判断为负值。至于为什么会这样,也许是平台和编译器的差异吧,我的能力也解答不了这个问题。感兴趣的朋友可以继续深入研究。程序的原作者可能为了节省arduino nano上的内存空间,所以选用了char作为变量的类型,但是移植到ESP8266的时候,这样的差异就造成了程序执行出现偏差。最后的解决办法是把函数返回值的类型改为int,程序就正常工作了。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值