一、先看看下面的小程序:
#include <stdio.h> #include <stdlib.h> typedef struct _STSTAFFINFO { char *pName; /*姓名*/ int iId; /*ID*/ }stStaffInfo; /*根据ID获取姓名*/ char* GetStaffNameById(int iId) { int i; stStaffInfo stTmpInfo[] = { {"Socrates", 1}, {"dyx1024", 2}, {"Kevin", 3}, {"Jim", 4} }; for (i = 0; i < sizeof(stTmpInfo) / sizeof(stTmpInfo[0]); i++) { if (stTmpInfo[i].iId == iId) { return stTmpInfo[i].pName; } } return "No match Name"; } int main(int argc, char *argv[]) { int iId = 2; char *pName = GetStaffNameById(iId); printf("Staff Name is : %s(id = %d)\n", pName, iId); system("PAUSE"); return 0; }运行结果: Staff Name is : dyx1024(id = 2) 请按任意键继续. . .
运行结果与预期相符,但此程序却是一个有问题的程序,stTmpInfo是一个定义在函数GetStaffNameById中的临时变量,调用完此程序,它即被销毁,所以main函数中,pName所指对象的值是不确定的,在没被覆盖前,正确( 像此程序),但若被其他的函数调用覆盖,谁也不知道其值是什么。
二、如何改进?
方法有以下四种,推荐使用方法三。
1、将stTmpInfo定义为全局变量,如下
#include <stdio.h> #include <stdlib.h> typedef struct _STSTAFFINFO { char *pName; /*姓名*/ int iId; /*ID*/ }stStaffInfo; static stStaffInfo stTmpInfo[] = { {"Socrates", 1}, {"dyx1024", 2}, {"Kevin", 3}, {"Jim", 4} }; /*根据ID获取姓名*/ char* GetStaffNameById(int iId) { int i; for (i = 0; i < sizeof(stTmpInfo) / sizeof(stTmpInfo[0]); i++) { if (stTmpInfo[i].iId == iId) { return stTmpInfo[i].pName; } } return "No match Name"; } int main(int argc, char *argv[]) { int iId = 2; char *pName = GetStaffNameById(iId); printf("Staff Name is : %s(id = %d)\n", pName, iId); system("PAUSE"); return 0; }2、程序内部将stTmpInfo定义为static,如下: #include <stdio.h> #include <stdlib.h> typedef struct _STSTAFFINFO { char *pName; int iId; /*ID*/ }stStaffInfo; char* GetStaffNameById(int iId) { int i; static stStaffInfo stTmpInfo[] = { {"Socrates", 1}, {"dyx1024", 2}, {"Kevin", 3}, {"Jim", 4} }; for (i = 0; i < sizeof(stTmpInfo) / sizeof(stTmpInfo[0]); i++) { if (stTmpInfo[i].iId == iId) { return stTmpInfo[i].pName; } } return "No match Name"; } int main(int argc, char *argv[]) { int iId = 2; char *pName = GetStaffNameById(iId); printf("Staff Name is : %s(id = %d)\n", pName, iId); system("PAUSE"); return 0; }
3、修改接口,通过出参取回。 #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct _STSTAFFINFO { char *pName; int iId; }stStaffInfo; void GetStaffNameById(int iId, int iNameLen, char *pOutName) { int i; stStaffInfo stTmpInfo[] = { {"Socrates", 1}, {"dyx1024", 2}, {"Kevin", 3}, {"Jim", 4} }; if (NULL == pOutName) { return; } for (i = 0; i < sizeof(stTmpInfo) / sizeof(stTmpInfo[0]); i++) { if (stTmpInfo[i].iId == iId) { strncpy(pOutName, stTmpInfo[i].pName, iNameLen); return; } } strncpy(pOutName, "No match Name", iNameLen); return; } int main(int argc, char *argv[]) { int iId = 20; char szName[21] = "\0"; GetStaffNameById(iId, 20, szName); printf("Staff Name is : %s(id = %d)\n", szName, iId); system("PAUSE"); return 0; }
4、通过子程序分配内存,调用者释放解决。
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct _STSTAFFINFO { char *pName; /*NAME*/ int iId; /*ID*/ }stStaffInfo; /*?ù?YID??è?D???*/ char* GetStaffNameById(int iId) { int i; int iMaxNameLen = 20; stStaffInfo stTmpInfo[] = { {"Socrates", 1}, {"dyx1024", 2}, {"Kevin", 3}, {"Jim", 4} }; char *pRetName = (char *)malloc(iMaxNameLen); if (NULL == pRetName) { exit(1); } for (i = 0; i < sizeof(stTmpInfo) / sizeof(stTmpInfo[0]); i++) { if (stTmpInfo[i].iId == iId) { strncpy(pRetName, stTmpInfo[i].pName, iMaxNameLen); return pRetName; } } strncpy(pRetName, "No match Name", iMaxNameLen); return pRetName; } int main(int argc, char *argv[]) { int iId = 2; char *pName = GetStaffNameById(iId); printf("Staff Name is : %s(id = %d)\n", pName, iId); free(pName); pName = NULL; system("PAUSE"); return 0; }