函数的参数是指向声明为 const 的参数的指针,如何处理?
Function's parameter that is a pointer to an argument that was declared as const, how to handle it?
我正在为PIC 使用MikroC,我不知道编译器的名称。我正在使用 PIC18F4550。我需要在 16x4 LCD 中打印菜单的列表。我在这里放了一段代码,因为代码很大放在这里,所以,我试着在这里写一个最小的可重现的例子。
代码按以下方式工作:我有一个堆栈来存储菜单,菜单结构包含标题和项目数量等字段。
在文件中 main.c
#include "menu.h"
int main(){
unsigned char error;
error = 0;
Tstack stackMenus;
error = menu_push(&stackMenus, &mainMenu);
}
============================================= ============
在文件中menu.c
#include "menu.h"
const Tmenu mainMenu = {
4,
"Main Menu"
};
unsigned char menu_push( Tstack *s, PTmenu item ){
unsigned char error = 0;
if(s->topo == 9){
return 1;
}
s->pilha[++s->topo] = item;
return error;
}
============================================= =========
在文件中menu.h
struct Smenu {
unsigned char numberOfItens;
char *Title;
};
typedef struct Smenu Tmenu;
typedef Tmenu *PTmenu;
struct Sstack {
PTmenu stack[10];
signed char top;
};
typedef struct Sstack Tstack;
extern Tmenu mainMenu;
Terro menu_push(Tstack *s, PTmenu item);
我将 mainMenu 声明为 const,将其作为参数传递给 menu_stack。然而,编译器抱怨说它是 "Illegal pointer conversion"。
我试着做
unsigned char menu_push( Tstack *s, Tmenu * const item ){ ...}
和
unsigned char menu_push( Tstack *s, const Tmenu * item ){ ...}
但是出现了同样的信息,"Illegal pointer conversion"。
我该如何处理?我需要将 mainMenu 声明为 const,因为还有其他菜单,而且我使用的是 RAM 内存大小受限的微控制器。
这段代码在相当严格的编译选项下编译得很干净。将您的母语代码转换为翻译后的英语框架需要进行大量细微的更改。但是,我已经将 PTmenu
作为一种类型消除了(如评论中所暗示)——Is it a good idea to typedef pointers? 的答案通常是 "No".
menu.h
typedef unsigned char Terro;
struct Smenu
{
unsigned char numberOfItens;
char *Title;
};
typedef struct Smenu Tmenu;
struct Sstack
{
const Tmenu *stack[10];
signed char top;
};
typedef struct Sstack Tstack;
extern const Tmenu mainMenu;
Terro menu_push(Tstack *s, const Tmenu *item);
main.c
#include "menu.h"
#include <stdio.h>
int main(void)
{
unsigned char error;
Tstack stackMenus = { { 0 }, 0 };
error = menu_push(&stackMenus, &mainMenu);
printf("Error = %d\n", error);
}
menu.c
#include "menu.h"
const Tmenu mainMenu =
{
4,
"Main Menu"
};
unsigned char menu_push(Tstack *s, const Tmenu *item)
{
unsigned char error = 0;
if (s->top == 9)
{
return 1;
}
s->stack[++s->top] = item;
return error;
}
在 MacBook Pro 上使用 GCC 9.1.0 测试编译(到 object 文件)运行 macOS 10.14.6 Mojave:
$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes -c menu47.c
$
代码仍然存在问题 — if (s->top == 9)
行是恶魔般的。
它应该更像 if (s->top < 10)
除了 10
应该是一个名称,用于标识 Tstack
中 stack
数组的大小——我可能会在 enum { STACK_SIZE = 10 };
然后在数组维度和测试中使用它。这个名字有点太笼统了——它很容易与其他筹码大小发生冲突。但这取决于您的用例,并且让我们走得很远。 menu.h
文件中应该有 header 个守卫(#ifndef MENU_H_INCLUDED
/ #define MENU_H_INCLUDED
/ …header 的内容… / #endif
)。结构元素的大写是随意的。 main()
中的变量 error
应该是 Terro
类型。 menu.c
中函数的 return 类型应该与 menu.h
中的声明匹配——它也应该是 Terro
。等等
我正在为PIC 使用MikroC,我不知道编译器的名称。我正在使用 PIC18F4550。我需要在 16x4 LCD 中打印菜单的列表。我在这里放了一段代码,因为代码很大放在这里,所以,我试着在这里写一个最小的可重现的例子。
代码按以下方式工作:我有一个堆栈来存储菜单,菜单结构包含标题和项目数量等字段。
在文件中 main.c
#include "menu.h"
int main(){
unsigned char error;
error = 0;
Tstack stackMenus;
error = menu_push(&stackMenus, &mainMenu);
}
============================================= ============
在文件中menu.c
#include "menu.h"
const Tmenu mainMenu = {
4,
"Main Menu"
};
unsigned char menu_push( Tstack *s, PTmenu item ){
unsigned char error = 0;
if(s->topo == 9){
return 1;
}
s->pilha[++s->topo] = item;
return error;
}
============================================= =========
在文件中menu.h
struct Smenu {
unsigned char numberOfItens;
char *Title;
};
typedef struct Smenu Tmenu;
typedef Tmenu *PTmenu;
struct Sstack {
PTmenu stack[10];
signed char top;
};
typedef struct Sstack Tstack;
extern Tmenu mainMenu;
Terro menu_push(Tstack *s, PTmenu item);
我将 mainMenu 声明为 const,将其作为参数传递给 menu_stack。然而,编译器抱怨说它是 "Illegal pointer conversion"。 我试着做
unsigned char menu_push( Tstack *s, Tmenu * const item ){ ...}
和
unsigned char menu_push( Tstack *s, const Tmenu * item ){ ...}
但是出现了同样的信息,"Illegal pointer conversion"。
我该如何处理?我需要将 mainMenu 声明为 const,因为还有其他菜单,而且我使用的是 RAM 内存大小受限的微控制器。
这段代码在相当严格的编译选项下编译得很干净。将您的母语代码转换为翻译后的英语框架需要进行大量细微的更改。但是,我已经将 PTmenu
作为一种类型消除了(如评论中所暗示)——Is it a good idea to typedef pointers? 的答案通常是 "No".
menu.h
typedef unsigned char Terro;
struct Smenu
{
unsigned char numberOfItens;
char *Title;
};
typedef struct Smenu Tmenu;
struct Sstack
{
const Tmenu *stack[10];
signed char top;
};
typedef struct Sstack Tstack;
extern const Tmenu mainMenu;
Terro menu_push(Tstack *s, const Tmenu *item);
main.c
#include "menu.h"
#include <stdio.h>
int main(void)
{
unsigned char error;
Tstack stackMenus = { { 0 }, 0 };
error = menu_push(&stackMenus, &mainMenu);
printf("Error = %d\n", error);
}
menu.c
#include "menu.h"
const Tmenu mainMenu =
{
4,
"Main Menu"
};
unsigned char menu_push(Tstack *s, const Tmenu *item)
{
unsigned char error = 0;
if (s->top == 9)
{
return 1;
}
s->stack[++s->top] = item;
return error;
}
在 MacBook Pro 上使用 GCC 9.1.0 测试编译(到 object 文件)运行 macOS 10.14.6 Mojave:
$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes -c menu47.c
$
代码仍然存在问题 — if (s->top == 9)
行是恶魔般的。
它应该更像 if (s->top < 10)
除了 10
应该是一个名称,用于标识 Tstack
中 stack
数组的大小——我可能会在 enum { STACK_SIZE = 10 };
然后在数组维度和测试中使用它。这个名字有点太笼统了——它很容易与其他筹码大小发生冲突。但这取决于您的用例,并且让我们走得很远。 menu.h
文件中应该有 header 个守卫(#ifndef MENU_H_INCLUDED
/ #define MENU_H_INCLUDED
/ …header 的内容… / #endif
)。结构元素的大写是随意的。 main()
中的变量 error
应该是 Terro
类型。 menu.c
中函数的 return 类型应该与 menu.h
中的声明匹配——它也应该是 Terro
。等等