怎么在C语言中应用结构体实现c++类的思想
在结构体里定义一个函数成员,这样就可以运用类似c++类的成员函数
#include <stdio.h>
struct alink_stu
{
void (*pfuc)();
};
void iface_provcode_setvalue()
{
printf("iface_provCode_setvalue\n");
}
void iface_hwVer_setvalue()
{
printf("iface_hwVer_setvalue\n");
}
struct alink_stu init_alink[]=
{
{.pfuc=iface_provcode_setvalue},
{.pfuc=iface_hwVer_setvalue}
};
int main(int argc , char const *argv[])
{
int count = sizeof(init_alink)/sizeof(struct alink_stu);
for(int i=0; i<count; i++)
{
init_alink[i].pfuc();
}
return 0;
}
运行结果:
稍微加上枚举成员判断函数类型:
#include <stdio.h>
enum type_num
{
one=1,
two
};
struct alink_stu
{
union
{
char *(*pone)();
int (*ptwo)();
}pfuc;
enum type_num etype;
};
char *iface_provcode_setvalue()
{
printf("iface_provCode_setvalue\n");
return NULL;
}
int iface_hwVer_setvalue()
{
printf("iface_hwVer_setvalue\n");
return 0;
}
struct alink_stu init_alink[]=
{
{.pfuc.pone=iface_provcode_setvalue, .etype=one},
{.pfuc.ptwo=iface_hwVer_setvalue, .etype=two}
};
int main(int argc , char const *argv[])
{
int count = sizeof(init_alink)/sizeof(struct alink_stu);
for(int i=0; i<count; i++)
{
if(init_alink[i].etype==one)
{
init_alink[i].pfuc.pone();
printf("[type]:one\n");
}
else if(init_alink[i].etype==two)
{
init_alink[i].pfuc.ptwo();
printf("[type]:two\n");
}
else
{
printf("[type]:else\n");
}
}
return 0;
}
运行结果:
- system返回值是127或者-1 为执行失败:
实战应用:
实现初始化全局变量,通过结构体实现初始化具有一定共性的数据,简化代码,方便处理。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
enum ValType
{
TYPE_INT=1,
TYPE_CHAR //for string
};
struct Stu_AndLink
{
void (*pfuc)(FILE *fp, struct Stu_AndLink *init_alink);
enum ValType valtype;
char cfgitem[32];
char andlink_item[32];
void *value;
};
/*去除字符串多余字符包括前后空格和换行符\r\n*/
char *strip_string_extra_characters(char *str)
{
char buf[128] = "0";
int i = 0;
void *p = NULL;
if(NULL == str)
{
return NULL;
}
//删除首部一个或者连续的空格
for(i=0; i<strlen(str); i++)
{
if(' ' != str[i])
{
break;
}
}
if(' ' == str[0])
{
p = (void*)&str[i];
}
else
{
p = (void*)str;
}
//删除尾部空格和\r\n
for(i=strlen(str)-1; i>=0; i--)
{
if(' '==str[i] || '\r'==str[i] || '\n'==str[i])
continue;
else
break;
}
if(' '==str[i+1] || '\r'==str[i+1] || '\n'==str[i+1])
{
str[i+1] = '\0';
}
strcpy(buf, (char*)p);
bzero(str, strlen(str));
strcpy(str, buf);
return str;
}
void iface_value_init(FILE *fp, struct Stu_AndLink *init_alink)
{
char buf[128] = "0";
char linebuf[128] = "0";
char *p = NULL;
if(NULL == init_alink)
{
printf("[init_alink]:NULL!\n");
return ;
}
//优先读取cfg值
/*
if(!cfg_get_item(init_alink->cfgitem, buf, 128))
{
strip_string_extra_characters(buf); //除去多余空格和换行符号
if(0 != strlen(buf))
{
if(TYPE_INT == init_alink->valtype)
{
*((int*)(init_alink->value)) = atoi(buf);
}
else if(TYPE_CHAR == init_alink->valtype)
{
strcpy((char*)(init_alink->value), buf);
}
return ;
}
}
*/
//其次读取alink.conf
if(NULL == fp)
{
printf("[file]:not esxit!\n");
return ;
}
fseek(fp, 0, SEEK_SET);
while(fgets(linebuf, sizeof(linebuf), fp))
{
if(!strncasecmp(linebuf, init_alink->andlink_item, strlen(init_alink->andlink_item)))
{
p = strchr(linebuf, '=');
if(NULL != p)
{
bzero(buf, sizeof(buf));
strcpy(buf, (char*)(p+1));
strip_string_extra_characters(buf); //除去多余空格和换行符号
break;
}
}
bzero(linebuf, sizeof(linebuf));
}
if(0 != strlen(buf))
{
if(TYPE_INT == init_alink->valtype)
{
*((int*)(init_alink->value)) = atoi(buf);
}
else if(TYPE_CHAR == init_alink->valtype)
{
strcpy((char*)(init_alink->value), buf);
}
}
}
char alink_provcode[5] = "";
char alink_hwVer[32] = "";
int alink_dbgflag = 0;
struct Stu_AndLink init_alink[]=
{
{.pfuc=iface_value_init, .valtype=TYPE_CHAR, .cfgitem="ANDLINK_PROVINCE", .andlink_item="ALINK_PROVCODE", .value=(void*)alink_provcode},
{.pfuc=iface_value_init, .valtype=TYPE_CHAR, .cfgitem="SYS_HW_VER", .andlink_item="SYS_HW_VER", .value=(void*)alink_hwVer},
{.pfuc=iface_value_init, .valtype=TYPE_INT, .cfgitem="ANDLINK_DBGFLAG", .andlink_item="ALINK_DBGFLAG", .value=(void*)&alink_dbgflag}
};
int main(int argc , char const *argv[])
{
FILE *fp = fopen("./alink.conf", "r");
int count = sizeof(init_alink)/sizeof(struct Stu_AndLink);
for(int i=0; i<count; i++)
{
init_alink[i].pfuc(fp, &init_alink[i]);
}
printf("[alink_provcode]:%s\n", alink_provcode);
printf("[alink_hwVer]:%s\n", alink_hwVer);
printf("[alink_dbgflag]:%d\n", alink_dbgflag);
if(fp != NULL)
fclose(fp);
return 0;
}
C++类函数的重载应用,用函数嵌套来实现。
void iface_value_init_xxxx(FILE *fp, struct Stu_AndLink *init_alink)
{
iface_value_init(fp, init_alink);
...
}
使用宏优化累赘的结构体赋值:
#define INIT_TYPE_CHAR(A,B,C) {.pfuc=iface_value_init, .valtype=TYPE_CHAR, .cfgitem=A, .andlink_item=B, .value=(void*)C, .valsize=sizeof(C)}
#define INIT_TYPE_INT(A,B,C) {.pfuc=iface_value_init, .valtype=TYPE_INT, .cfgitem=A, .andlink_item=B, .value=(void*)&C, .valsize=sizeof(C)}
struct Stu_AndLink init_alink[]=
{
INIT_TYPE_INT("ANDLINK_DBGFLAG", "ALINK_DBGFLAG", alink_dbgflag),
INIT_TYPE_INT("ANDLINK_AUTHMODE", "ALINK_AUTHMODE", alink_authmode),
INIT_TYPE_CHAR("ANDLINK_DEVICETYPE", "ALINK_DEVICETYPE", alink_devicetype),
INIT_TYPE_CHAR("ANDLINK_PRODUCTOKEN", "ALINK_PRODUCTOKEN", alink_producttoken),
INIT_TYPE_CHAR("SYS_HW_VER", "SYS_HW_VER", alink_fwversion),
INIT_TYPE_CHAR("SYS_FW_USER_VER", "SYS_FW_USER_VER", alink_swVer),
INIT_TYPE_CHAR("ANDLINK_DEVICEVENDOR", "ALINK_DEVICEVENDOR", alink_devicevendor),
INIT_TYPE_CHAR("ANDLINK_DEVICEMODEL", "ALINK_DEVICEMODEL", alink_devicemode),
INIT_TYPE_CHAR("SYS_DEVIVE_SN", "SYS_DEVIVE_SN", alink_devicesn),
INIT_TYPE_INT("ANDLINK_WIFI5G_SUPPORT", "ALINK_WIFI5G_SUPPORT", alink_radio5),
INIT_TYPE_INT("SYS_FLASH_SIZE", "SYS_FLASH_SIZE", alink_flashSize),
INIT_TYPE_INT("SYS_RAM_SIZE", "SYS_RAM_SIZE", alink_ramSize),
INIT_TYPE_CHAR("ANDLINK_CPUTYPE", "ALINK_CPUTYPE", alink_cputype),
INIT_TYPE_CHAR("SYS_HW_VER", "SYS_HW_VER", alink_hwVer),
INIT_TYPE_CHAR("ANDLINK_RESERVER", "ALINK_RESERVER", alink_reserve),
INIT_TYPE_CHAR("SYS_DEVICE_CMEI", "SYS_DEVICE_CMEI", alink_cmei),
INIT_TYPE_CHAR("ANDLINK_AUTHID", "ALINK_AUTHID", alink_authid),
INIT_TYPE_CHAR("ANDLINK_DEVKEY", "ALINK_DEVKEY", alink_devkey),
INIT_TYPE_CHAR("ANDLINK_PROVINCE", "ALINK_PROVCODE", alink_provcode),
{.pfuc=iface_value_init_pppoeuser, .valtype=TYPE_CHAR, .cfgitem="USR_BROADBAND_USERNAME", .andlink_item="USR_BROADBAND_USERNAME", .value=(void*)alink_pppoeuser, .valsize=sizeof(alink_pppoeuser)},
{.pfuc=iface_value_init_upLinkEthName, .valtype=TYPE_CHAR, .cfgitem="ANDLINK_CAPTUREETH", .andlink_item="ALINK_CAPTUREETH", .value=(void*)alink_captureeth, .valsize=sizeof(alink_captureeth)},
};