我正在使用仅支持C90的Keil C51 C编译器对8051微控制器进行编程。
我想通过UART发送一个字节的数据,该函数如下所示:
void Uart_send(char data){
//...
}
使用1:
char a = 123;
Uart_send(a); //work great
使用2:
Uart_send(123);//doesn't work, but no error or warning from compiler
在后一种情况下,发送的是1个字节,但不是正确的值(123)。
如果我将代码更改为:
void Uart_send(const char data){
//...
}
然后一切正常。
根据我的理解以及互联网上的多种资源,“ const”的唯一目的是防止函数更改其自变量(换句话说,防止程序员错误地更改自变量)。那为什么我的第二种方法不起作用?
编辑:这是我的完整代码:
UART.h
typedef struct {
char Buffer[10];
char *p;
char Ready;
void (*Load)(char Data);
void (*Transmit)();
void (*Flush)();
} _uart;
extern _uart UART;
UART.c
#include "UART.h"
#include <reg51.h>
#define EOF 0x00
/*
0000_0000: EOF
0000_0001: countdown
1xxx_xxxx: primary time set
1xxx_xxxx: secondary time set
0111_xxxx: set phase
*/
#define Wait() for(i = 0; i < 3; ++i)
void Load(const char Data){
*UART.p = Data;
if(Data == EOF){
UART.Ready = 1;
}
++UART.p;
}
void Transmit(){
int i;
char *p;
p = UART.Buffer;
while(1){
SBUF = *p;
while(~TI);
TI = 0;
Wait();//make sure slave finish process data before sending next byte
if(*p == EOF) break;//we are done
++p;
}
UART.Flush();
}
void Flush(){
UART.p = UART.Buffer;
UART.Ready = 0;
}
_uart UART = {
{EOF, EOF, EOF, EOF, EOF, EOF, EOF, EOF, EOF, EOF},
UART.Buffer, 0,
Load,
Transmit,
Flush
};
main.c
#include "UART.h"
//.....
UART.Load(123);
UART.Load(0x00); //0x00 = EOF
UART.Transmit();
答案 0 :(得分:5)
现在,当我们看到您的代码时,问题就很清楚了:您的头文件中没有函数声明(原型)。
在C语言中,您确实需要先声明事物,然后才能使用它们,否则编译器将不了解它们。
请注意,此处的标准版本之间有很大差异。在较早的C标准(在C99之前)中,使用函数会通过从调用中推断出参数类型来隐式声明(在您的情况下,这是错误的,因为123
是int
)。从C99开始,这实际上不再允许了。
答案 1 :(得分:2)
除避免错误外,还使用const参数
编译器可以使用const
进行一些优化。