C 常量参数的目的不是避免错误
我正在用keil C51 C编译器编程8051微控制器,它只支持C90 我想通过UART发送一个字节的数据,函数如下所示:C 常量参数的目的不是避免错误,c,keil,c51,C,Keil,C51,我正在用keil C51 C编译器编程8051微控制器,它只支持C90 我想通过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(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;
通用异步收发器
#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
};
常量参数的目的不是避免错误
编译器可以使用当前的
常量进行一些优化。现在,当我们看到您的代码时,问题就很清楚了:头文件中没有函数声明(原型)
在C语言中,您确实需要在使用它们之前声明它们,否则编译器将不知道它们
请注意,这里的标准版本之间有很大的差异。在旧的C标准(C99之前)中,使用函数将通过从调用中推断参数类型来隐式声明(在您的情况下,这是错误的,因为123
是int
)。从C99及以后,这是不允许的。在C中不允许,@Blazeconst
限定对象不是真正的“常量”。回想起来,我认为const
应该被命名为“readonly”
(包括引号以标记为不存在)。@Blaze Forcase
只能使用编译时常量。一个<代码> const 参数也不能是C++中的编译时常数。@ StutyToel:这也是可行的:在您所示的代码中,<代码>加载< <代码>函数指针在<代码> < UART < /COD> <代码>结构> /COD>之间有区别,并且实际函数<代码>加载<代码>似乎有原型?
#include "UART.h"
//.....
UART.Load(123);
UART.Load(0x00); //0x00 = EOF
UART.Transmit();