RELATEED CONSULTING
相关咨询
选择下列产品马上在线沟通
服务时间:8:30-17:00
你可能遇到了下面的问题
关闭右侧工具栏

新闻中心

这里有您想知道的互联网营销解决方案
结构体中指针赋值问题的分析及C代码示例

问题描述

某结构体的定义如下:

 
 
  1. typedef struct 
  2. { 
  3.     int     iAge;                // 年龄 
  4.     char    szAddr1[100];        // 地址1 
  5.     char   *pszAddr2;            // 地址2 
  6.     char  **pszAddr3;            // 地址3 
  7. } T_PeopleInfo; 

请问如何对结构体中的各个成员变量(尤其是指针变量)进行赋值?

问题分析及C代码示例

我们可以看到,在结构体T_PeopleInfo中,pszAddr2和pszAddr3均为指针,其中pszAddr2为一级指针,pszAddr3为二级指针。本文的重点,就是要找到对一级指针和二级指针赋值的正确方法。

我们把结构体T_PeopleInfo放到具体的C代码中,以直观地展现对结构体中的各个成员变量的赋值方法。

我们首先编写如下程序(程序1):

 
 
  1. /********************************************************************** 
  2. * 版权所有 (C)2016, Zhou Zhaoxiong。 
  3. * 
  4. * 文件名称:PointerTest.c 
  5. * 文件标识:无 
  6. * 内容摘要:演示指针的用法 
  7. * 其它说明:无 
  8. * 当前版本:V1.0 
  9. * 作    者:Zhou Zhaoxiong 
  10. * 完成日期:20160712 
  11. * 
  12. **********************************************************************/ 
  13. #include  
  14.  
  15.  
  16. // 重定义数据类型 
  17. typedef signed   int        INT32; 
  18. typedef unsigned int        UINT32; 
  19. typedef unsigned char       UINT8; 
  20.  
  21. // 结构体定义 
  22. typedef struct 
  23. { 
  24.     UINT32   iAge;                    // 年龄 
  25.     UINT8    szAddr1[100];            // 地址1 
  26.     UINT8   *pszAddr2;                // 地址2 
  27.     UINT8  **pszAddr3;                // 地址3 
  28. } T_PeopleInfo; 
  29.  
  30.  
  31. /**************************************************************** 
  32. * 功能描述: 主函数 
  33. * 输入参数: 无 
  34. * 输出参数: 无 
  35. * 返 回 值: 0-执行完成 
  36. * 其他说明: 无 
  37. * 修改日期       版本号        修改人        修改内容 
  38. * ------------------------------------------------------------- 
  39. * 20160712        V1.0     Zhou Zhaoxiong     创建 
  40. ****************************************************************/ 
  41. INT32 main(void) 
  42. { 
  43.     T_PeopleInfo tPeopleInfo = {0}; 
  44.  
  45.     // 结构体变量赋值 
  46.     // 对iAge赋值 
  47.     tPeopleInfo.iAge = 10; 
  48.  
  49.     // 对szAddr1赋值 
  50.     strncpy(tPeopleInfo.szAddr1, "Chongqing, China!", strlen("Chongqing, China!")); 
  51.  
  52.     // 对pszAddr2赋值 
  53.     strncpy(tPeopleInfo.pszAddr2, "Chengdu, China!", strlen("Chengdu, China!")); 
  54.  
  55.     // 对pszAddr3赋值 
  56.     strncpy(tPeopleInfo.pszAddr3, "Wuhan, China!", strlen("Wuhan, China!")); 
  57.  
  58.     // 打印变量的值 
  59.     printf("Age=%d, Addr1=%s, Addr2=%s, Addr3=%s", tPeopleInfo.iAge, tPeopleInfo.szAddr1, tPeopleInfo.pszAddr2, tPeopleInfo.pszAddr3); 
  60.  
  61.     return 0; 
  62. } 
  63.  

在程序1中,我们按照对结构体中的数组的赋值方法对指针赋值,程序可以编译通过,但运行的时候,程序便会挂掉。究其原因,是因为没有为pszAddr2和pszAddr3指针分配内存空间。

我们对程序1进行改进,编写出以下程序(程序2):

 
 
  1. /********************************************************************** 
  2. * 版权所有 (C)2016, Zhou Zhaoxiong。 
  3. * 
  4. * 文件名称:PointerTest.c 
  5. * 文件标识:无 
  6. * 内容摘要:演示指针的用法 
  7. * 其它说明:无 
  8. * 当前版本:V1.0 
  9. * 作    者:Zhou Zhaoxiong 
  10. * 完成日期:20160712 
  11. * 
  12. **********************************************************************/ 
  13. #include  
  14.  
  15.  
  16. // 重定义数据类型 
  17. typedef signed   int        INT32; 
  18. typedef unsigned int        UINT32; 
  19. typedef signed   char       INT8; 
  20.  
  21. // 结构体定义 
  22. typedef struct 
  23. { 
  24.     UINT32   iAge;                    // 年龄 
  25.     INT8     szAddr1[100];            // 地址1 
  26.     INT8    *pszAddr2;                // 地址2 
  27.     INT8   **pszAddr3;                // 地址3 
  28. } T_PeopleInfo; 
  29.  
  30.  
  31. /**************************************************************** 
  32. * 功能描述: 主函数 
  33. * 输入参数: 无 
  34. * 输出参数: 无 
  35. * 返 回 值: 0-执行完成 
  36. * 其他说明: 无 
  37. * 修改日期       版本号        修改人        修改内容 
  38. * ------------------------------------------------------------- 
  39. * 20160712        V1.0     Zhou Zhaoxiong     创建 
  40. ****************************************************************/ 
  41. INT32 main(void) 
  42. { 
  43.     T_PeopleInfo tPeopleInfo = {0}; 
  44.  
  45.     // 结构体变量赋值 
  46.     // 对iAge赋值 
  47.     tPeopleInfo.iAge = 10; 
  48.  
  49.     // 对szAddr1赋值 
  50.     strncpy(tPeopleInfo.szAddr1, "Chongqing, China!", strlen("Chongqing, China!")); 
  51.  
  52.     // 对pszAddr2赋值 
  53.     tPeopleInfo.pszAddr2 = (INT8 *)malloc(100); 
  54.     if (tPeopleInfo.pszAddr2 == NULL) 
  55.     { 
  56.         return -1; 
  57.     } 
  58.     strncpy(tPeopleInfo.pszAddr2, "Chengdu, China!", strlen("Chengdu, China!")); 
  59.  
  60.     // 对pszAddr3赋值 
  61.     tPeopleInfo.pszAddr3 = (INT8 *)malloc(100); 
  62.     if (tPeopleInfo.pszAddr3 == NULL) 
  63.     { 
  64.         return -2; 
  65.     } 
  66.     strncpy(tPeopleInfo.pszAddr3, "Wuhan, China!", strlen("Wuhan, China!")); 
  67.  
  68.     // 打印变量的值 
  69.     printf("Age=%d, Addr1=%s, Addr2=%s, Addr3=%s\n", tPeopleInfo.iAge, tPeopleInfo.szAddr1, tPeopleInfo.pszAddr2, tPeopleInfo.pszAddr3); 
  70.  
  71.     return 0; 
  72. } 

在程序2中,我们先使用malloc为pszAddr2和pszAddr3分配了内存空间(注意,执行malloc之后,要判断指针是否为空),此时就可以将变量值赋给它们。程序编译和运行都是正常的,输出结果如下:

 
 
  1. ~/zhouzx/Test/PointerTest> PointerTest  
  2. Age=10, Addr1=Chongqing, China!, Addr2=Chengdu, China!, Addr3=Wuhan, China! 

除了程序2可以实现对一级指针和二级指针的正常赋值之外,我们还可以编写如下程序(程序3):

 
 
  1. * 版权所有 (C)2016, Zhou Zhaoxiong。 
  2. * 
  3. * 文件名称:PointerTest.c 
  4. * 文件标识:无 
  5. * 内容摘要:演示指针的用法 
  6. * 其它说明:无 
  7. * 当前版本:V1.0 
  8. * 作    者:Zhou Zhaoxiong 
  9. * 完成日期:20160712 
  10. * 
  11. **********************************************************************/ 
  12. #include  
  13.  
  14.  
  15. // 重定义数据类型 
  16. typedef signed   int        INT32; 
  17. typedef unsigned int        UINT32; 
  18. typedef signed   char       INT8; 
  19.  
  20. // 结构体定义 
  21. typedef struct 
  22. { 
  23.     UINT32   iAge;                    // 年龄 
  24.     INT8     szAddr1[100];            // 地址1 
  25.     INT8    *pszAddr2;                // 地址2 
  26.     INT8   **pszAddr3;                // 地址3 
  27. } T_PeopleInfo; 
  28.  
  29.  
  30. /**************************************************************** 
  31. * 功能描述: 主函数 
  32. * 输入参数: 无 
  33. * 输出参数: 无 
  34. * 返 回 值: 0-执行完成 
  35. * 其他说明: 无 
  36. * 修改日期       版本号        修改人        修改内容 
  37. * ------------------------------------------------------------- 
  38. * 20160712        V1.0     Zhou Zhaoxiong     创建 
  39. ****************************************************************/ 
  40. INT32 main(void) 
  41. { 
  42.     T_PeopleInfo tPeopleInfo = {0}; 
  43.  
  44.     // 结构体变量赋值 
  45.     // 对iAge赋值 
  46.     tPeopleInfo.iAge = 10; 
  47.  
  48.     // 对szAddr1赋值 
  49.     strncpy(tPeopleInfo.szAddr1, "Chongqing, China!", strlen("Chongqing, China!")); 
  50.  
  51.     // 对pszAddr2赋值 
  52.     tPeopleInfo.pszAddr2 = "Chengdu, China!"; 
  53.  
  54.     // 对pszAddr3赋值 
  55.     tPeopleInfo.pszAddr3 = "Wuhan, China!"; 
  56.  
  57.     // 打印变量的值 
  58.     printf("Age=%d, Addr1=%s, Addr2=%s, Addr3=%s\n", tPeopleInfo.iAge, tPeopleInfo.szAddr1, tPeopleInfo.pszAddr2, tPeopleInfo.pszAddr3); 
  59.  
  60.     return 0; 
  61. } 
  62.  

在程序3中,我们直接将字符串赋给了pszAddr2和pszAddr3,也就是将这两个字符串的首地址赋给了指针。那么,指针所指向的地址中存放的内容就是字符串的值。程序编译和运行都是正常的,输出结果如下:

 
 
  1. ~/zhouzx/Test/PointerTest> PointerTest  
  2. Age=10, Addr1=Chongqing, China!, Addr2=Chengdu, China!, Addr3=Wuhan, China! 

另,对于二级指针的赋值,我们还可以编写如下程序(程序4):

 
 
  1. /********************************************************************** 
  2. * 版权所有 (C)2016, Zhou Zhaoxiong。 
  3. * 
  4. * 文件名称:PointerTest.c 
  5. * 文件标识:无 
  6. * 内容摘要:演示指针的用法 
  7. * 其它说明:无 
  8. * 当前版本:V1.0 
  9. * 作    者:Zhou Zhaoxiong 
  10. * 完成日期:20160712 
  11. * 
  12. **********************************************************************/ 
  13. #include  
  14.  
  15.  
  16. // 重定义数据类型 
  17. typedef signed   int        INT32; 
  18. typedef unsigned int        UINT32; 
  19. typedef signed   char       INT8; 
  20.  
  21. // 结构体定义 
  22. typedef struct 
  23. { 
  24.     UINT32   iAge;                    // 年龄 
  25.     INT8     szAddr1[100];            // 地址1 
  26.     INT8    *pszAddr2;                // 地址2 
  27.     INT8   **pszAddr3;                // 地址3 
  28. } T_PeopleInfo; 
  29.  
  30.  
  31. /**************************************************************** 
  32. * 功能描述: 主函数 
  33. * 输入参数: 无 
  34. * 输出参数: 无 
  35. * 返 回 值: 0-执行完成 
  36. * 其他说明: 无 
  37. * 修改日期       版本号        修改人        修改内容 
  38. * ------------------------------------------------------------- 
  39. * 20160712        V1.0     Zhou Zhaoxiong     创建 
  40. ****************************************************************/ 
  41. INT32 main(void) 
  42. { 
  43.     T_PeopleInfo tPeopleInfo = {0}; 
  44.  
  45.     // 结构体变量赋值 
  46.     // 对iAge赋值 
  47.     tPeopleInfo.iAge = 10; 
  48.  
  49.     // 对szAddr1赋值 
  50.     strncpy(tPeopleInfo.szAddr1, "Chongqing, China!", strlen("Chongqing, China!")); 
  51.  
  52.     // 对pszAddr2赋值 
  53.     tPeopleInfo.pszAddr2 = "Chengdu, China!"; 
  54.  
  55.     // 对pszAddr3赋值 
  56.     tPeopleInfo.pszAddr3 = (INT8 *)malloc(100); 
  57.     if (tPeopleInfo.pszAddr3 == NULL) 
  58.     { 
  59.         return -1; 
  60.     } 
  61.     *(tPeopleInfo.pszAddr3) = "Wuhan, China!"; 
  62.  
  63.     // 打印变量的值 
  64.     printf("Age=%d, Addr1=%s, Addr2=%s, Addr3=%s\n", tPeopleInfo.iAge, tPeopleInfo.szAddr1, tPeopleInfo.pszAddr2, *(tPeopleInfo.pszAddr3)); 
  65.  
  66.     return 0; 
  67. } 

在程序4中,我们先用malloc为pszAddr3分配了内存空间,然后便可以使用该指针来接收字符串变量的值(注意,这里是将“Wuhan, China!”赋给了*(tPeopleInfo.pszAddr3))。程序编译和运行都是正常的,输出结果如下:

 
 
  1. ~/zhouzx/Test/PointerTest> PointerTest  
  2. Age=10, Addr1=Chongqing, China!, Addr2=Chengdu, China!, Addr3=Wuhan, China! 

总结

本文对结构体中指针赋值问题进行了分析,并用C代码演示了指针的赋值方法。

在实际的C语言项目中,很多程序出现问题,就是对指针的处理不当造成的。因此,熟练掌握各种指针的使用方法,是对一个合格的软件开发人员的基本要求。

【本文是专栏作者周兆熊的原创文章,作者微信公众号:周氏逻辑(logiczhou)】


分享名称:结构体中指针赋值问题的分析及C代码示例
网站路径:http://www.aqpgk.com/article/coejdco.html