C语言内的宏变量问题

Code_Fly 2014-09-22 08:55:48
问题如下:
早期系统中定义了一些宏,格式如下#define MAX_VOIP_EXTEN 256
因此在后续的开发中,有很多例如 char voip_exten[ MAX_VOIP_EXTEN]这种代码。
现在,项目希望MAX_VOIP_EXTEN的值是从数据库读取,而不是宏定义。考虑到很多处地方已经应用了
char voip_exten[ MAX_VOIP_EXTEN]这样的代码,
所有请问大家,有无办法将变量(从数据库读取)转换成宏(MAX_VOIP_EXTEN)
...全文
659 33 打赏 收藏 转发到动态 举报
写回复
用AI写文章
33 条回复
切换为时间正序
请发表友善的回复…
发表回复
Code_Fly 2014-09-30
  • 打赏
  • 举报
回复
引用 29 楼 mymtom 的回复:
由于C99支持VLA(variable length array), 如果char voip_exten[ MAX_VOIP_EXTEN]是局部变量,而且不是某结构体的成员,就比较简单了,MAX_VOIP_EXTEN 定义成一个变量,程序启动的时候从数据库给这个变量赋值就就可以了。

#include <stdio.h>

#define MAX_VOIP_EXTEN  256

/* 增加三行就好了 */
int g_max_voip_exten;
#undef  MAX_VOIP_EXTEN
#define MAX_VOIP_EXTEN  g_max_voip_exten

int foo(void)
{
    char voip_exten[ MAX_VOIP_EXTEN];

    printf("%d\n", (int)sizeof(voip_exten));
    return 0;
}

int
main(int argc, char *argv[])
{

    g_max_voip_exten = argc;

    foo();

    return 0;
}
即使在C99中增加了对VLA的支持,但是还是不能初始化VLA,
mymtom 2014-09-26
  • 打赏
  • 举报
回复
由于C99支持VLA(variable length array), 如果char voip_exten[ MAX_VOIP_EXTEN]是局部变量,而且不是某结构体的成员,就比较简单了,MAX_VOIP_EXTEN 定义成一个变量,程序启动的时候从数据库给这个变量赋值就就可以了。

#include <stdio.h>

#define MAX_VOIP_EXTEN  256

/* 增加三行就好了 */
int g_max_voip_exten;
#undef  MAX_VOIP_EXTEN
#define MAX_VOIP_EXTEN  g_max_voip_exten

int foo(void)
{
    char voip_exten[ MAX_VOIP_EXTEN];

    printf("%d\n", (int)sizeof(voip_exten));
    return 0;
}

int
main(int argc, char *argv[])
{

    g_max_voip_exten = argc;

    foo();

    return 0;
}
LouisScola 2014-09-26
  • 打赏
  • 举报
回复
你需要的值大于MAX_VOIP_EXTEN吗?大于就必须改源码,小于还好说
Code_Fly 2014-09-26
  • 打赏
  • 举报
回复
引用 29 楼 mymtom 的回复:
由于C99支持VLA(variable length array), 如果char voip_exten[ MAX_VOIP_EXTEN]是局部变量,而且不是某结构体的成员,就比较简单了,MAX_VOIP_EXTEN 定义成一个变量,程序启动的时候从数据库给这个变量赋值就就可以了。

#include <stdio.h>

#define MAX_VOIP_EXTEN  256

/* 增加三行就好了 */
int g_max_voip_exten;
#undef  MAX_VOIP_EXTEN
#define MAX_VOIP_EXTEN  g_max_voip_exten

int foo(void)
{
    char voip_exten[ MAX_VOIP_EXTEN];

    printf("%d\n", (int)sizeof(voip_exten));
    return 0;
}

int
main(int argc, char *argv[])
{

    g_max_voip_exten = argc;

    foo();

    return 0;
}
恩阿,学习了。 听老师这么讲,这个做法好像还是有局限性的
Code_Fly 2014-09-26
  • 打赏
  • 举报
回复
引用 27 楼 zhao4zhong1 的回复:
那就只有将源代码改为动态分配。
恩阿。多谢老师。本来是想,在新的支持协议中有取巧的办法解决这个问题
赵4老师 2014-09-25
  • 打赏
  • 举报
回复
引用 22 楼 BeanJoy 的回复:
[quote=引用 20 楼 zhao4zhong1 的回复:] 楼主会代码生成(Code Generation)技术吗?
从数据库取出值,然后生成代码,然后编译,然后发布。 如果用户那数据库中值修改了,然后再生成新代码,再编译,再发布? 可行吗?[/quote] 为什么不可行?
BeanJoy 2014-09-25
  • 打赏
  • 举报
回复
引用 20 楼 zhao4zhong1 的回复:
楼主会代码生成(Code Generation)技术吗?
从数据库取出值,然后生成代码,然后编译,然后发布。 如果用户那数据库中值修改了,然后再生成新代码,再编译,再发布? 可行吗?
赵4老师 2014-09-25
  • 打赏
  • 举报
回复
那就只有将源代码改为动态分配。
Code_Fly 2014-09-25
  • 打赏
  • 举报
回复
引用 24 楼 BeanJoy 的回复:
[quote=引用 23 楼 zhao4zhong1 的回复:] [quote=引用 22 楼 BeanJoy 的回复:] [quote=引用 20 楼 zhao4zhong1 的回复:] 楼主会代码生成(Code Generation)技术吗?
从数据库取出值,然后生成代码,然后编译,然后发布。 如果用户那数据库中值修改了,然后再生成新代码,再编译,再发布? 可行吗?[/quote] 为什么不可行?[/quote] 可行是可行。 但是这样不得在客户机器上装编译环境,不得把相应的代码拷到客户机器上,在更改数据库一个值后,还得先编译了再运行,谁能接受?反正我是接受不了。[/quote] 这样子就是我这边再打个临时版本给客户,根本起不到远程修改的效果
赵4老师 2014-09-25
  • 打赏
  • 举报
回复
如果不想将源代码改为动态分配,别无他法。
BeanJoy 2014-09-25
  • 打赏
  • 举报
回复
引用 23 楼 zhao4zhong1 的回复:
[quote=引用 22 楼 BeanJoy 的回复:] [quote=引用 20 楼 zhao4zhong1 的回复:] 楼主会代码生成(Code Generation)技术吗?
从数据库取出值,然后生成代码,然后编译,然后发布。 如果用户那数据库中值修改了,然后再生成新代码,再编译,再发布? 可行吗?[/quote] 为什么不可行?[/quote] 可行是可行。 但是这样不得在客户机器上装编译环境,不得把相应的代码拷到客户机器上,在更改数据库一个值后,还得先编译了再运行,谁能接受?反正我是接受不了。
xiaohuh421 2014-09-24
  • 打赏
  • 举报
回复
纯C语言是不支持动态数组的. C++也只有支持高版C++标准的可以支持动态数组. 你的问题就是动态数组问题. 宏就是一个编译时的文本替换. 所以不可能实现你的需求. 目前来看, 你只能动态分配 , 别无它法了.
赵4老师 2014-09-24
  • 打赏
  • 举报
回复
楼主会代码生成(Code Generation)技术吗?
Code_Fly 2014-09-23
  • 打赏
  • 举报
回复
引用 10 楼 xiaohuh421 的回复:
宏, 不是常量也不是变量. 只是编译时的文本替换. 你的问题, 只需要动态申请内存即可. 动态数组, 只有C++高版本的标准才支持.
并不是动态问题,是要根据数据库改变宏的值,而使得char aaa[MAX_VOIP_EXTEN]这类(很多)数组依旧可用,而不是全部改用malloc
lsjfdjoijvtghu 2014-09-23
  • 打赏
  • 举报
回复
数据下标要确定,我还以为是寻址时要常量,原来是在说定义数组的时候。
赵4老师 2014-09-23
  • 打赏
  • 举报
回复
仅供参考
//codegen.c
// 输入一组字符串,比如
// aa ss ddd dd 33 dd
// 然后自动生成一个函数 int A(const char*);
// 实现A("aa")返回0  A("ss")返回1 依次类推
#include <stdio.h>
int main(int argc,char **argv) {
    int i;
    if (argc<2) {
        printf("%s p1 [p2 ...] [>result.c]\nGenerate code int A(const char *a); 0==A(\"p1\") 1==A(\"p2\") ...",argv[0]);
        return 1;
    }
    //printf("#include <string.h>\n");
    printf("int A(const char *a) {\n");
    for (i=0;i<argc-1;i++) {
        printf("    if (0==strcmp(a,\"%s\")) return %d;\n",argv[i+1],i);
    }
    printf("    return -1;\n");
    printf("}\n");
    return 0;
}
//C:\test\Debug>codegen.exe
//codegen.exe p1 [p2 ...] [>result.c]
//Generate code int A(const char *a); 0==A("p1") 1==A("p2") ...
//C:\test\Debug>codegen.exe aa ss ddd dd 33 dd
//int A(const char *a) {
//    if (0==strcmp(a,"aa")) return 0;
//    if (0==strcmp(a,"ss")) return 1;
//    if (0==strcmp(a,"ddd")) return 2;
//    if (0==strcmp(a,"dd")) return 3;
//    if (0==strcmp(a,"33")) return 4;
//    if (0==strcmp(a,"dd")) return 5;
//    return -1;
//}
//
//c:\test\Debug>codegen.exe aa ss ddd dd 33 dd >result.c
//
//c:\test\Debug>type result.c
//int A(const char *a) {
//    if (0==strcmp(a,"aa")) return 0;
//    if (0==strcmp(a,"ss")) return 1;
//    if (0==strcmp(a,"ddd")) return 2;
//    if (0==strcmp(a,"dd")) return 3;
//    if (0==strcmp(a,"33")) return 4;
//    if (0==strcmp(a,"dd")) return 5;
//    return -1;
//}
//
jwj070524 2014-09-23
  • 打赏
  • 举报
回复
引用 3 楼 Code_Fly 的回复:
[quote=引用 2 楼 jwj070524 的回复:] 直接是不行,C语言不是动态的。一种折中的办法是,先在代码中用undef编译指令取消这些宏定义,然后重新使用这些被取消的符号变成全局变量,之后写一个从数据库中读出这些变量的函数,在程序初始化阶段给这些全局变量赋值。
那这样子那些宏全部变成全局变量,不能作为数组的大小[/quote]
引用 4 楼 lovesmiles 的回复:
[quote=引用 2 楼 jwj070524 的回复:] 直接是不行,C语言不是动态的。一种折中的办法是,先在代码中用undef编译指令取消这些宏定义,然后重新使用这些被取消的符号变成全局变量,之后写一个从数据库中读出这些变量的函数,在程序初始化阶段给这些全局变量赋值。
别胡扯,在C语言里面数组下标不能用变量表示,必须是编译期就明确的常量和宏。[/quote] C99支持variable length array,所以如果用GCC的话是可以的。
gojoy_x13 2014-09-23
  • 打赏
  • 举报
回复
可以考虑把数据库中取出的值作为数组的最大有效范围的游标吗?如果直接想简单的修改宏,感觉边角困难
xiaohuh421 2014-09-23
  • 打赏
  • 举报
回复
宏, 不是常量也不是变量. 只是编译时的文本替换. 你的问题, 只需要动态申请内存即可. 动态数组, 只有C++高版本的标准才支持.
灌水号 2014-09-23
  • 打赏
  • 举报
回复
malloc不能用啊?
加载更多回复(12)

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧