函数的参数是指向声明为 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 应该是一个名称,用于标识 Tstackstack 数组的大小——我可能会在 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。等等