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

版权声明:本文为博主原创文章,对文章内容有任何意见或建议,欢迎与作者单独交流,作者QQ(微信):245924426。 https://blog.csdn.net/zhouzxi/article/details/51892960

问题描述 

某结构体的定义如下:

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

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

问题分析及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
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63

在程序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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72

在程序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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62

在程序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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67

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

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

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

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

  • 插入代码
  •      
查看评论
1楼  a11730820382016-07-14 19:32发表 [回复] [引用] [举报]
请问本文代码能够编译通过吗?按照您给出的源码貌似行不通耶
Re:  Programmer_Zhou2016-07-15 07:16发表 [回复] [引用] [举报]
可以编译通过,我是在linux下编译的。

结构体初始化及结构体指针.结构体数组.结构体函数的调用赋值等

#include "stdio.h" #include "stdlib.h" #include "string.h" int fun(void); int ARRSCORE[3]={133,123...
  • wangweijundeqq
  • wangweijundeqq
  • 2017-07-30 15:55:29
  • 1559

C语言 结构体与结构体指针用法总结

  • SYQ_aa
  • SYQ_aa
  • 2017-08-20 17:03:18
  • 1848
在C语言开发中,结构体用到的机会很多。所谓结构体,就是定义一种里面包含多种元素的变量。 我们来看一个简单的例子。比如你想定义一个书名列表然后为每本书创建书名和作者作为书的信息。结构体变量定义如下: s...
广告

c 结构体中存在指针,指针的不同赋值方法

  • hao_rh
  • hao_rh
  • 2017-06-15 10:13:32
  • 651
#include#include#includestruct parameter{ char *fd; int hit;};int main() { struct parameter*pptr = (...

含有指针成员的结构体使用总结

  • u012273127
  • u012273127
  • 2016-08-31 19:54:13
  • 11590
在C++中经常用到结构体和指针,当定义一个结构体,结构体成员中有指针的时候,需要注意很多。一下分为:结构体初始化、结构体作为函数参数、函数返回值、以及结构体指针的情况进行总结。 一、含有指针成员的结构...

结构体指针的定义和引用

  • amj0622
  • amj0622
  • 2009-10-10 11:26:00
  • 44974
作者:不祥  来源于:网络  发布时间:2005-10-5 指针变量非常灵活方便,可以指向任一类型的变量,若定义指针变量指向结构体类型变量,则可以通过指针来引用结构体类型变量。7.3.1 指向结构体类...

关于结构体变量指针

  • u010456460
  • u010456460
  • 2016-05-20 15:46:46
  • 3568
程序中使用结构体类型指针引用结构体变量的成员,需要通过C提供的函数malloc()来为指针分配安全的地址。 最近在结构体上做了个实验: 声明一个结构体类型,如下: typedef struct...

结构体定义、结构体指针、内存分配、指针、结构体形参的深入理解

/*********结构体定义、结构体指针、内存分配、指针、结构体形参的深入理解****  作者: 攀枝花学院 袁伟明  邮箱:[email protected]  说明:此程序为深入学习数据结...
  • yuanweiming1992
  • yuanweiming1992
  • 2015-02-25 23:17:07
  • 3615

c语言中结构体指针

  • frank_jb
  • frank_jb
  • 2015-07-29 21:59:57
  • 8085
1、指向结构体的指针变量: C 语言中->是一个整体,它是用于指向结构体,假设我们在程序中定义了一个结构体,然后声明一个指针变量指向这个结构体,那么我们要用指针取出结构体中的数据,就要用到指向运算符“...

C语言中结构体的直接赋值

  • naturebe
  • naturebe
  • 2012-08-17 15:07:27
  • 94086
一直记得C语言中,结构体是不可以直接赋值的。我问了三个同学,都说在C++中可以,在C语言中不可以,需要逐一成员赋值或者用memcpy函数。 我测试了一下如下的程序: #include #inclu...

指针的赋值与引用的赋值

  • chenzongduozhu
  • chenzongduozhu
  • 2016-11-19 11:30:04
  • 2905
1.指针的赋值 int a = 24; int *p = &a;//指针的初始化 *p = 25;//指针的赋值 2.引用的赋值 int a = 24; int b = 0; int &...

C++ 指针的两种操作,通过指针赋值 & 对指针赋值

// 打印函数 template void disp(T i) { cout
  • u012560212
  • u012560212
  • 2017-12-18 14:42:04
  • 1740

指针铁律2/3:间接赋值是指针存在的最大意义

  • bbs375
  • bbs375
  • 2016-09-13 08:55:01
  • 523
1)两码事:指针变量和它指向的内存块变量 2)条件反射:指针指向某个变量,就是把某个变量地址否给指针 3)*p间接赋值成立条件:3个条件          a) 2个变量(通常一个实参,一个形...

C语言指针的初始化和赋值

  • mhjcumt
  • mhjcumt
  • 2012-06-28 22:46:55
  • 110336
1、指针的初始化 指针初始化时,“=”的右操作数必须为内存中数据的地址,不可以是变量,也不可以直接用整型地址值(但是int*p=0;除外,该语句表示指针为空)。此时,*p只是表示定义的是个指针变...

1.4 间接赋值是指针存在的最大意义

  • starbarks
  • starbarks
  • 2017-03-03 13:40:09
  • 658
/* 间接赋值成立的三个条件 条件1:定义了一个变量(实参)定义了一个变量(形参) 条件2:建立关联,//实参取地址传给形参 条件3://*p形参,去间接的修改实参的值 main —>func...

C语言指针详解----指针声明定义赋值

  • sinat_35821976
  • sinat_35821976
  • 2017-02-24 10:22:20
  • 1231
C语言的指针是让新手很头疼的事情,但是由于其太过于灵活,以至于可以很好得的解决一些复杂的问题,因此不得不掌握。我最近正在学习指针相关的内容,因此在这里做一个小的总结。本篇是不涉及到函数以及结构体等复杂...

c语言中通过指针将数值赋值到制定内存地址

  • wht15501032502
  • wht15501032502
  • 2017-03-07 19:21:29
  • 957
1.一种直观的方法   假设现在需要往内存0x12ff7c地址上存入一个整型数0x100。我们怎么才能做到呢? 我们知道可以通过一个指针向其指向的内存地址写入数据,那么这里的内存地址0x12ff7c其...

经典的指针错误,在方法中,指针不要相互赋值,应该赋这个指针的内容。

猜你喜欢

转载自blog.csdn.net/mianhuantang848989/article/details/80025027