C 常量参数的目的不是避免错误

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)

我正在用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(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中不允许,@Blaze
const
限定对象不是真正的“常量”。回想起来,我认为
const
应该被命名为
“readonly”
(包括引号以标记为不存在)。@Blaze For
case
只能使用编译时常量。一个<代码> const 参数也不能是C++中的编译时常数。@ StutyToel:这也是可行的:在您所示的代码中,<代码>加载< <代码>函数指针在<代码> < UART < /COD> <代码>结构> /COD>之间有区别,并且实际函数<代码>加载<代码>似乎有原型?
#include "UART.h"
//.....
UART.Load(123);
UART.Load(0x00); //0x00 = EOF
UART.Transmit();