结构体中指针赋值问题的分析及C代码示例

简介: 问题描述 某结构体的定义如下:typedef struct{ int iAge; // 年龄 char szAddr1[...

问题描述
某结构体的定义如下:

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

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

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

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

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

/**********************************************************************
* 版权所有 (C)2016, Zhou Zhaoxiong。
*
* 文件名称:PointerTest.c
* 文件标识:无
* 内容摘要:演示指针的用法
* 其它说明:无
* 当前版本:V1.0
* 作    者:Zhou Zhaoxiong
* 完成日期:20160712
*
**********************************************************************/
#include <stdio.h>


// 重定义数据类型
typedef signed   int        INT32;
typedef unsigned int        UINT32;
typedef unsigned char       UINT8;

// 结构体定义
typedef struct
{
    UINT32   iAge;                    // 年龄
    UINT8    szAddr1[100];            // 地址1
    UINT8   *pszAddr2;                // 地址2
    UINT8  **pszAddr3;                // 地址3
} T_PeopleInfo;


/****************************************************************
* 功能描述: 主函数
* 输入参数: 无
* 输出参数: 无
* 返 回 值: 0-执行完成
* 其他说明: 无
* 修改日期       版本号        修改人        修改内容
* -------------------------------------------------------------
* 20160712        V1.0     Zhou Zhaoxiong     创建
****************************************************************/
INT32 main(void)
{
    T_PeopleInfo tPeopleInfo = {0};

    // 结构体变量赋值
    // 对iAge赋值
    tPeopleInfo.iAge = 10;

    // 对szAddr1赋值
    strncpy(tPeopleInfo.szAddr1, "Chongqing, China!", strlen("Chongqing, China!"));

    // 对pszAddr2赋值
    strncpy(tPeopleInfo.pszAddr2, "Chengdu, China!", strlen("Chengdu, China!"));

    // 对pszAddr3赋值
    strncpy(tPeopleInfo.pszAddr3, "Wuhan, China!", strlen("Wuhan, China!"));

    // 打印变量的值
    printf("Age=%d, Addr1=%s, Addr2=%s, Addr3=%s", tPeopleInfo.iAge, tPeopleInfo.szAddr1, tPeopleInfo.pszAddr2, tPeopleInfo.pszAddr3);

    return 0;
}

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

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

/**********************************************************************
* 版权所有 (C)2016, Zhou Zhaoxiong。
*
* 文件名称:PointerTest.c
* 文件标识:无
* 内容摘要:演示指针的用法
* 其它说明:无
* 当前版本:V1.0
* 作    者:Zhou Zhaoxiong
* 完成日期:20160712
*
**********************************************************************/
#include <stdio.h>


// 重定义数据类型
typedef signed   int        INT32;
typedef unsigned int        UINT32;
typedef signed   char       INT8;

// 结构体定义
typedef struct
{
    UINT32   iAge;                    // 年龄
    INT8     szAddr1[100];            // 地址1
    INT8    *pszAddr2;                // 地址2
    INT8   **pszAddr3;                // 地址3
} T_PeopleInfo;


/****************************************************************
* 功能描述: 主函数
* 输入参数: 无
* 输出参数: 无
* 返 回 值: 0-执行完成
* 其他说明: 无
* 修改日期       版本号        修改人        修改内容
* -------------------------------------------------------------
* 20160712        V1.0     Zhou Zhaoxiong     创建
****************************************************************/
INT32 main(void)
{
    T_PeopleInfo tPeopleInfo = {0};

    // 结构体变量赋值
    // 对iAge赋值
    tPeopleInfo.iAge = 10;

    // 对szAddr1赋值
    strncpy(tPeopleInfo.szAddr1, "Chongqing, China!", strlen("Chongqing, China!"));

    // 对pszAddr2赋值
    tPeopleInfo.pszAddr2 = (INT8 *)malloc(100);
    if (tPeopleInfo.pszAddr2 == NULL)
    {
        return -1;
    }
    strncpy(tPeopleInfo.pszAddr2, "Chengdu, China!", strlen("Chengdu, China!"));

    // 对pszAddr3赋值
    tPeopleInfo.pszAddr3 = (INT8 *)malloc(100);
    if (tPeopleInfo.pszAddr3 == NULL)
    {
        return -2;
    }
    strncpy(tPeopleInfo.pszAddr3, "Wuhan, China!", strlen("Wuhan, China!"));

    // 打印变量的值
    printf("Age=%d, Addr1=%s, Addr2=%s, Addr3=%s\n", tPeopleInfo.iAge, tPeopleInfo.szAddr1, tPeopleInfo.pszAddr2, tPeopleInfo.pszAddr3);

    return 0;
}

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

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

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

/**********************************************************************
* 版权所有 (C)2016, Zhou Zhaoxiong。
*
* 文件名称:PointerTest.c
* 文件标识:无
* 内容摘要:演示指针的用法
* 其它说明:无
* 当前版本:V1.0
* 作    者:Zhou Zhaoxiong
* 完成日期:20160712
*
**********************************************************************/
#include <stdio.h>


// 重定义数据类型
typedef signed   int        INT32;
typedef unsigned int        UINT32;
typedef signed   char       INT8;

// 结构体定义
typedef struct
{
    UINT32   iAge;                    // 年龄
    INT8     szAddr1[100];            // 地址1
    INT8    *pszAddr2;                // 地址2
    INT8   **pszAddr3;                // 地址3
} T_PeopleInfo;


/****************************************************************
* 功能描述: 主函数
* 输入参数: 无
* 输出参数: 无
* 返 回 值: 0-执行完成
* 其他说明: 无
* 修改日期       版本号        修改人        修改内容
* -------------------------------------------------------------
* 20160712        V1.0     Zhou Zhaoxiong     创建
****************************************************************/
INT32 main(void)
{
    T_PeopleInfo tPeopleInfo = {0};

    // 结构体变量赋值
    // 对iAge赋值
    tPeopleInfo.iAge = 10;

    // 对szAddr1赋值
    strncpy(tPeopleInfo.szAddr1, "Chongqing, China!", strlen("Chongqing, China!"));

    // 对pszAddr2赋值
    tPeopleInfo.pszAddr2 = "Chengdu, China!";

    // 对pszAddr3赋值
    tPeopleInfo.pszAddr3 = "Wuhan, China!";

    // 打印变量的值
    printf("Age=%d, Addr1=%s, Addr2=%s, Addr3=%s\n", tPeopleInfo.iAge, tPeopleInfo.szAddr1, tPeopleInfo.pszAddr2, tPeopleInfo.pszAddr3);

    return 0;
}

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

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

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

/**********************************************************************
* 版权所有 (C)2016, Zhou Zhaoxiong。
*
* 文件名称:PointerTest.c
* 文件标识:无
* 内容摘要:演示指针的用法
* 其它说明:无
* 当前版本:V1.0
* 作    者:Zhou Zhaoxiong
* 完成日期:20160712
*
**********************************************************************/
#include <stdio.h>


// 重定义数据类型
typedef signed   int        INT32;
typedef unsigned int        UINT32;
typedef signed   char       INT8;

// 结构体定义
typedef struct
{
    UINT32   iAge;                    // 年龄
    INT8     szAddr1[100];            // 地址1
    INT8    *pszAddr2;                // 地址2
    INT8   **pszAddr3;                // 地址3
} T_PeopleInfo;


/****************************************************************
* 功能描述: 主函数
* 输入参数: 无
* 输出参数: 无
* 返 回 值: 0-执行完成
* 其他说明: 无
* 修改日期       版本号        修改人        修改内容
* -------------------------------------------------------------
* 20160712        V1.0     Zhou Zhaoxiong     创建
****************************************************************/
INT32 main(void)
{
    T_PeopleInfo tPeopleInfo = {0};

    // 结构体变量赋值
    // 对iAge赋值
    tPeopleInfo.iAge = 10;

    // 对szAddr1赋值
    strncpy(tPeopleInfo.szAddr1, "Chongqing, China!", strlen("Chongqing, China!"));

    // 对pszAddr2赋值
    tPeopleInfo.pszAddr2 = "Chengdu, China!";

    // 对pszAddr3赋值
    tPeopleInfo.pszAddr3 = (INT8 *)malloc(100);
    if (tPeopleInfo.pszAddr3 == NULL)
    {
        return -1;
    }
    *(tPeopleInfo.pszAddr3) = "Wuhan, China!";

    // 打印变量的值
    printf("Age=%d, Addr1=%s, Addr2=%s, Addr3=%s\n", tPeopleInfo.iAge, tPeopleInfo.szAddr1, tPeopleInfo.pszAddr2, *(tPeopleInfo.pszAddr3));

    return 0;
}

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

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

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

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

目录
相关文章
|
21天前
|
存储 C语言
C语言如何使用结构体和指针来操作动态分配的内存
在C语言中,通过定义结构体并使用指向该结构体的指针,可以对动态分配的内存进行操作。首先利用 `malloc` 或 `calloc` 分配内存,然后通过指针访问和修改结构体成员,最后用 `free` 释放内存,实现资源的有效管理。
81 12
|
21天前
|
存储 人工智能 算法
数据结构实验之C 语言的函数数组指针结构体知识
本实验旨在复习C语言中的函数、数组、指针、结构体与共用体等核心概念,并通过具体编程任务加深理解。任务包括输出100以内所有素数、逆序排列一维数组、查找二维数组中的鞍点、利用指针输出二维数组元素,以及使用结构体和共用体处理教师与学生信息。每个任务不仅强化了基本语法的应用,还涉及到了算法逻辑的设计与优化。实验结果显示,学生能够有效掌握并运用这些知识完成指定任务。
43 4
|
2月前
|
存储 搜索推荐 C语言
深入C语言指针,使代码更加灵活(二)
深入C语言指针,使代码更加灵活(二)
|
2月前
|
存储 程序员 编译器
深入C语言指针,使代码更加灵活(一)
深入C语言指针,使代码更加灵活(一)
|
2月前
|
C语言
深入C语言指针,使代码更加灵活(三)
深入C语言指针,使代码更加灵活(三)
深入C语言指针,使代码更加灵活(三)
|
3月前
|
存储 Go
Go: struct 结构体类型和指针【学习笔记记录】
本文是Go语言中struct结构体类型和指针的学习笔记,包括结构体的定义、成员访问、使用匿名字段,以及指针变量的声明使用、指针数组定义使用和函数传参修改值的方法。
|
4月前
|
存储 大数据 测试技术
掌握 GoLang 中的指针:高效代码的提示和技巧
掌握 GoLang 中的指针:高效代码的提示和技巧
|
4月前
|
存储 C语言
指针与结构体
指针与结构体
35 0
|
6月前
|
搜索推荐 程序员 C语言
指针赋值与引用传递:C语言的基础知识与实践技巧
指针赋值与引用传递:C语言的基础知识与实践技巧
|
6月前
|
Go C++
代码随想录——双指针/滑动窗口(二)
代码随想录——双指针/滑动窗口(二)