将uint16_t变量乘以数字会产生奇怪的结果

kev*_*nlu 5 c

我有一个非常简单的C代码,给我带来了奇怪的结果.我正在为Micaz微粒开发一个简单的无线传感器网络应用程序.它似乎有ATmega128L 8位AVR微处理器.我正在使用AVR studio编写和编译代码.

uint16_t myvariable;
uint16_t myresult;
myresult = myvariable*256;
Run Code Online (Sandbox Code Playgroud)

当myvariable为3时,我发现myresult总是重置为512.只是想知道它为什么会这样工作.我的猜测是,这样一个字数256和uint16_t的混合物神奇地导致了这个问题.但我不知道为什么.有人可以对此作出详细解释吗?感谢任何帮助!

更详细的源代码如下.

static uint16_t myvariable[2];
static uint8_t AckMsg[32];
uint16_t myresult[MAX_SENDERS];

void protocol()  
{           
    if(thisnodeid != 5){   // sender nodes
      while (1)
      {         
        if(AckReceived && !MsgSent) {
          // If ACK received and a new message not sent yet,
          // send a new message on sending node.
        }

        else if(!AckReceived && MsgSent)
        {
            lib_radio_receive_timed(16, 32, AckMsg, 120);
            myvariable[0] = AckMsg[0];
            myvariable[1] = AckMsg[1];
            // Bug!!!, variable overflowed.
            myresult[thisnodeid] = 256*myvariable[1] + myvariable[0];  
        }

      }
    }           

}
Run Code Online (Sandbox Code Playgroud)

我真正想弄清楚的是,编译器如何编译以下代码行,因为我知道这行代码会导致错误.提前感谢您的任何信息!

myresult[thisnodeid] = 256*myvariable[1] + myvariable[0]; 
Run Code Online (Sandbox Code Playgroud)

当myvariable [1] = 3,myvariable [0] = 0时,我总是得到myresult [] = 512.看起来768总是重置为512.只是不知道为什么.

Vin*_*ent 1

我在标准系统上尝试了这段代码,没有任何问题:

#include <stdio.h>
#include <string.h>
#include <stdint.h>
#define MAX_SENDERS 10
static uint16_t myvariable[2];
static uint8_t AckMsg[32];
uint16_t myresult[MAX_SENDERS];
main()
{
    AckMsg[0] = 0;
    AckMsg[1] = 3;
    myvariable[0] = AckMsg[0];
    myvariable[1] = AckMsg[1];
    myresult[0] = 256*myvariable[1] + myvariable[0];  
    printf("%d", (int)myresult[0]);
}
Run Code Online (Sandbox Code Playgroud)

因此,要调试代码,您应该尝试替换以下行:

myvariable[0] = AckMsg[0];
myvariable[1] = AckMsg[1];
// Bug!!!, variable overflowed.
myresult[thisnodeid] = 256*myvariable[1] + myvariable[0]; 
Run Code Online (Sandbox Code Playgroud)

经过 :

uint16_t tmp;
myvariable[0] = AckMsg[0];
myvariable[1] = AckMsg[1];
tmp = 256*myvariable[1] + myvariable[0]; 
myresult[thisnodeid] = 256*myvariable[1] + myvariable[0]; 
printf("%d %d\n", (int)(AckMsg[0]), (int)(AckMsg[1]));
printf("%d %d\n", (int)(thisnodeid), (int)(MAX_SENDERS));
printf("%d %d\n", (int)(myvariable[0]), (int)(myvariable[1]));
printf("%d %d\n", (int)(tmp), (int)(myresult[thisnodeid]));
Run Code Online (Sandbox Code Playgroud)

这可能会带来有关问题根源的有用信息。

如果您无法在调试器中打印某些内容,您可以尝试以下操作:

uint16_t i = 0;
uint16_t n = 255;
myresult[thisnodeid] += myvariable[1];
while (i != n) {
    myresult[thisnodeid] += myvariable[1];
    i += 1;
}
myresult[thisnodeid] += myvariable[0]; 
Run Code Online (Sandbox Code Playgroud)

它会很慢,但它可以让您检测到实际发生溢出的位置,因为唯一大于 255 的变量是myresult