You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MCU CLI开发:如何不使用数组与#define预处理指令使用字符串字面量?

问题描述
  • 为栈空间仅约1kB的微控制器实现命令行接口(CLI)函数
  • 希望避免使用栈上数组存储命令字符串,防止占用宝贵的栈空间
  • 编码规范禁止在函数定义内部使用#define
  • 需要找到一种方案:无需#define和栈数组,同时能结合sizeof运算符处理命令字符串

原代码示例(注释已转译):

#include <stdio.h>
#include <string.h>

#define ARRAY_COUNT(a) (sizeof(a)/sizeof(a[0]))

int cli(int argc, char *argv[])
{
#if 1
    // 编码规范不允许在函数定义内使用#define
    #define fetch "fetch"
    #define push "push"
    #define quit "quit"
#else
    // 数组会分配在栈上,而栈空间非常小
    const char fetch[] = "fetch";
    const char push[] = "push";
    const char quit[] = "quit";
#endif
    if (1 < argc) {
        if (!strncmp(argv[1], fetch, ARRAY_COUNT(fetch)-1)) {
            // 执行fetch操作...
        } else if (!strncmp(argv[1], push, ARRAY_COUNT(push)-1)) {
            // 执行push操作...
        } else if (!strncmp(argv[1], quit, ARRAY_COUNT(quit)-1)) {
            // 执行quit操作...
        }
    }

    return 0; 
}
解决方案

直接使用字符串字面量结合sizeof即可,字符串字面量会被编译器放在只读数据段(ROM),不会占用栈空间,同时完全符合编码规范:

#include <stdio.h>
#include <string.h>

int cli(int argc, char *argv[])
{
    if (1 < argc) {
        // 直接用字符串字面量,sizeof("fetch")包含末尾的'\0',减1得到有效字符数
        if (!strncmp(argv[1], "fetch", sizeof("fetch") - 1)) {
            // 执行fetch操作...
        } else if (!strncmp(argv[1], "push", sizeof("push") - 1)) {
            // 执行push操作...
        } else if (!strncmp(argv[1], "quit", sizeof("quit") - 1)) {
            // 执行quit操作...
        }
    }

    return 0; 
}

方案说明

  • 字符串字面量(如"fetch")属于编译期常量,存储在只读数据区(通常是Flash/ROM),不会占用栈空间,完美适配小栈空间的MCU场景
  • sizeof("fetch")会在编译期计算出字符串的总长度(包括末尾的终止符'\0'),减1后正好是命令的有效字符数,和原代码中ARRAY_COUNT(fetch)-1的效果完全一致
  • 无需任何#define或栈数组,完全符合编码规范要求

内容的提问来源于stack exchange,提问作者albin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 03:15:36