一、先看看下面的小程序:
[cpp] #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;
}
#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;
}
運行結果:
[plain]
Staff Name is : dyx1024(id = 2)
請按任意鍵繼續. . .
Staff Name is : dyx1024(id = 2)
請按任意鍵繼續. . .
運行結果與預期相符,但此程序卻是一個有問題的程序,stTmpInfo是一個定義在函數GetStaffNameById中的臨時變量,調用完此程序,它即被銷毀,所以main函數中,pName所指對象的值是不確定的,在沒被覆蓋前,正確( 像此程序),但若被其他的函數調用覆蓋,誰也不知道其值是什麼。
二、如何改進?
方法有以下四種,推薦使用方法三。
1、將stTmpInfo定義為全局變量,如下
[cpp]
#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");<span style="white-space:pre"> </span>
return 0;
}
#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");<span style="white-space:pre"> </span>
return 0;
}
2、程序內部將stTmpInfo定義為static,如下:
[cpp]
#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;
}
#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、修改接口,通過出參取回。
[cpp]
#include <stdio.h>
#include <stdlib.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;
}
#include <stdio.h>
#include <stdlib.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、通過子程序分配內存,調用者釋放解決。
[cpp]
#include <stdio.h>
#include <stdlib.h>
typedef struct _STSTAFFINFO
{
char *pName; /*ÐÕÃû*/
int iId; /*ID*/
}stStaffInfo;
/*¸ù¾ÝID»ñÈ¡ÐÕÃû*/
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;
}
#include <stdio.h>
#include <stdlib.h>
typedef struct _STSTAFFINFO
{
char *pName; /*ÐÕÃû*/
int iId; /*ID*/
}stStaffInfo;
/*¸ù¾ÝID»ñÈ¡ÐÕÃû*/
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;
}
摘自 Socrates的專欄