向函数传递const unsigned char数组时的编译警告问题排查
数组传递函数时的编译器警告问题解释
我原本以为自己理解了数组向函数的传递方式,但以下代码显示我仍有不足。请帮忙解释编译器警告的问题,我已将代码精简到仍能复现错误的最小版本。
#include <stdio.h> typedef unsigned char uint8_t; typedef unsigned int uint16_t; const uint8_t sevensegment[18] = { 0x3F, // 0 0x06, // 1 0x5B, // 2 0x4F, // 3 0x66, // 4 0x6D, // 5 0x7D, // 6 0x07, // 7 0x7F, // 8 0x6F, // 9 0x77, // A 0x7C, // B 0x39, // C 0x5E, // D 0x79, // E 0x71, // F 0x00, // space 0x40, // minus }; void inttosevensegment(uint16_t num, uint8_t *display, uint8_t num_digits, const uint8_t *sevensegment) // integer to seven segment display using ht16k33 driver { uint8_t digit, lutindex; digit = num_digits-1; for (uint8_t i = 0; i < digit; i++) { display[i] = 0x00; } do { lutindex = num % 10 ; //lookuptable index num = num / 10; display[ digit--] = sevensegment[lutindex]; } while (num > 0); } int main(void) { uint16_t intnumber = 345; uint8_t num_digits = 4; uint8_t display[4]; inttosevensegment( intnumber, *display, num_digits, *sevensegment); for (int i = 0; i < 4; i++) { printf("buffer value = %X ", display[i]); } return 0; }
编译器警告信息
main.c: 在函数‘main’中: main.c:46:31: 警告:传递‘inttosevensegment’的参数2时在未进行强制转换的情况下将整数转换为指针 [-Wint-conversion] inttosevensegment( intnumber,*display,num_digits,*sevensegment); ^ main.c:25:6: 附注:期望‘uint8_t * {aka unsigned char *}’但实参的类型为‘uint8_t {aka unsigned char}’ void inttosevensegment( uint16_t num, uint8_t *display, uint8_t num_digits, const uint8_t *sevensegment) ^~~~~~~~~~~~~~~~~ main.c:46:51: 警告:传递‘inttosevensegment’的参数4时在未进行强制转换的情况下将整数转换为指针 [-Wint-conversion] inttosevensegment( intnumber,*display,num_digits,*sevensegment); ^ main.c:25:6: 附注:期望‘const uint8_t * {aka const unsigned char *}’但实参的类型为‘uint8_t {aka const unsigned char}’ void inttosevensegment( uint16_t num, uint8_t *display, uint8_t num_digits, const uint8_t *sevensegment) ^~~~~~~~~~~~~~~~~
问题原因与修正
错误根源
调用inttosevensegment时对数组名使用了解引用操作符*,这是核心问题:
*display:取的是数组display第一个元素的值(类型为uint8_t,单个字节整数),但函数参数要求的是uint8_t*(指向uint8_t的指针,即数组首地址)。*sevensegment:同理,取的是sevensegment数组第一个元素0x3F(整数类型),但函数需要的是const uint8_t*(指向常量uint8_t的指针)。
把整数当成指针传递,编译器会触发类型转换警告,运行时还可能导致非法内存访问。
修正代码
去掉数组名前的*,直接传递数组名即可:
inttosevensegment(intnumber, display, num_digits, sevensegment);
原理说明
在C语言中,数组名作为函数参数时,会自动隐式转换为指向数组首元素的指针。直接传递数组名,就等价于传递&display[0](数组首元素的地址),完全符合函数参数的类型要求。
内容的提问来源于stack exchange,提问作者oldPowerEngineer
相关产品推荐
相关产品推荐

