C:返回值为指针的函数解读

一、先看看下面的小程序:

#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; }

转载于:https://www.cnblogs.com/dyx1024/archive/2012/05/13/2556672.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值