c语言  结构体  函数  参数  传递

一、前言

本文中的程序实现对员工信息结构体字段赋值并打印出来的功能。该结构体的定义如下:

// 员工信息结构体
typedef struct
{INT8       szEmployeeName[100];     // 员工姓名UINT16  iEmployeeAge;                    // 员工年龄UINT32  iEmployeeNo;                      // 员工工号
} TEmployeeInfo;

函数GetEmployeeInfo用来对员工信息字段进行赋值,其声明如下:

INT32 GetEmployeeInfo(TEmployeeInfo *ptEmployeeInfo);

在主函数main中,采用两种参数传递的方法,一种是指针传递,另一种是非指针传递。

二、采用指针传递时的程序代码

采用指针传递时的程序代码如下:

/**********************************************************************

* 版权所有 (C)2014, Zhou Zhaoxiong。

*

* 文件名称: TestStruct.c

* 文件标识:无

* 内容摘要:用于演示结构体变量的用法

* 其它说明:无

* 当前版本: V1.0

* 作    者:

* 完成日期: 20170711

*

**********************************************************************/

#include <stdio.h>

#include <string.h>

// 数据类型

typedef signed   char INT8;

typedef unsigned char UINT16;

typedef unsigned int  UINT32;

typedef signed   int  INT32;

// 员工信息结构体

typedef struct

{

INT8    szEmployeeName[100];  // 员工姓名

UINT16  iEmployeeAge;         // 员工年龄

UINT32  iEmployeeNo;          // 员工工号

} TEmployeeInfo;

// 函数声明

INT32 GetEmployeeInfo(TEmployeeInfo *ptEmployeeInfo); // 获取员工信息函数

INT32 main(void);

/****************************************************************

* 功能描述:  主函数

* 输入参数:  无

* 输出参数:  无

* 返回值: 0-执行成功  -1-执行失败

* 其他说明:  无

* 修改日期        版本号        修改人        修改内容

* ----------------------------------------------------------------------------------------

* 20140617        V1.0      Zhou Zhaoxiong     创建

****************************************************************/

INT32 main(void)

{

INT32          iRetValue      = 0;       // 该变量用于表示调用GetEmployeeInfo函数返回的值

TEmployeeInfo *ptEmployeeInfo = NULL;    // 该变量用于存放员工信息

// 调用函数对员工信息字段赋值, 并打印出来

iRetValue = GetEmployeeInfo(ptEmployeeInfo);

if (iRetValue != 0)

{

printf("exec GetEmployeeInfo failed.\n");

return -1;

}

printf("员工信息为: \n姓名: %s\n年龄: %d\n工号: %d\n", ptEmployeeInfo->szEmployeeName, ptEmployeeInfo->iEmployeeAge, ptEmployeeInfo->iEmployeeNo);

return 0;

}

/**********************************************************************

* 功能描述:对员工信息字段赋值

* 输入参数: ptEmployeeInfo: 员工信息结构体

* 输出参数: ptEmployeeInfo: 员工信息结构体

* 返回值: 0-成功  -1-失败

* 其它说明:无

* 修改日期          版本号           修改人         修改内容

* --------------------------------------------------------------------------------------

* 20140617           V1.0         Zhou Zhaoxiong      创建

***********************************************************************/

INT32 GetEmployeeInfo(TEmployeeInfo *ptEmployeeInfo)

{

// 先对输入的指针参数进行异常判断

if (ptEmployeeInfo == NULL)

{

printf("Input parameter is NULL.\n");

return -1;

}

strncpy((char *)ptEmployeeInfo->szEmployeeName, "Li Yuanfang", strlen("Li Yuanfang"));   // 对姓名字段赋值

ptEmployeeInfo->iEmployeeAge = 100;       // 对年龄字段赋值

ptEmployeeInfo->iEmployeeNo  = 123456;    // 对工号字段赋值

return 0;     // 赋值成功, 返回0

}

程序的运行结果如图1所示:

图1 采用指针传递时的程序代码运行结果

从图1可以看出,函数GetEmployeeInfo的入参为空,不能实现赋值的功能。

三、改进后的采用指针传递时的程序代码

既然程序打印出指针为空的信息,那么我们先对传入的指针进行赋值操作是不是就可以了呢?

改进后的采用指针传递时的程序代码如下:

/**********************************************************************

* 版权所有 (C)2014, Zhou Zhaoxiong。

*

* 文件名称: TestStruct.c

* 文件标识:无

* 内容摘要:用于演示结构体变量的用法

* 其它说明:无

* 当前版本: V1.0

* 作    者:周兆熊

* 完成日期: 20140617

*

* 修改记录1:// 修改历史记录, 包括修改日期、版本号、修改人及修改内容

* 修改日期: 20140617

* 版本号: V1.0

* 修改人: Zhou Zhaoxiong

* 修改内容:创建

**********************************************************************/

#include <stdio.h>

#include <string.h>

// 数据类型

typedef signed   char INT8;

typedef unsigned char UINT16;

typedef unsigned int  UINT32;

typedef signed   int  INT32;

// 员工信息结构体

typedef struct

{

INT8    szEmployeeName[100];  // 员工姓名

UINT16  iEmployeeAge;         // 员工年龄

UINT32  iEmployeeNo;          // 员工工号

} TEmployeeInfo;

// 函数声明

INT32 GetEmployeeInfo(TEmployeeInfo *ptEmployeeInfo); // 获取员工信息函数

INT32 main(void);

/****************************************************************

* 功能描述:  主函数

* 输入参数:  无

* 输出参数:  无

* 返回值: 0-执行成功  -1-执行失败

* 其他说明:  无

* 修改日期        版本号        修改人        修改内容

* --------------------------------------------------------------------------------------------

* 20140617        V1.0      Zhou Zhaoxiong     创建

****************************************************************/

INT32 main(void)

{

INT32          iRetValue      = 0;       // 该变量用于表示调用GetEmployeeInfo函数返回的值

TEmployeeInfo *ptEmployeeInfo = NULL;    // 该变量用于存放员工信息

// 先对员工信息字段赋值, 防止空指针的存在

strncpy((char *)ptEmployeeInfo->szEmployeeName, "Di Renjie", strlen("Di Renjie"));   // 对姓名字段赋值

ptEmployeeInfo->iEmployeeAge = 150;       // 对年龄字段赋值

ptEmployeeInfo->iEmployeeNo  = 654321;    // 对工号字段赋值

// 调用函数对员工信息字段赋值, 并打印出来

iRetValue = GetEmployeeInfo(ptEmployeeInfo);

if (iRetValue != 0)

{

printf("exec GetEmployeeInfo failed.\n");

return -1;

}

printf("员工信息为: \n姓名: %s\n年龄: %d\n工号: %d\n", ptEmployeeInfo->szEmployeeName, ptEmployeeInfo->iEmployeeAge, ptEmployeeInfo->iEmployeeNo);

return 0;

}

/**********************************************************************

* 功能描述:对员工信息字段赋值

* 输入参数: ptEmployeeInfo: 员工信息结构体

* 输出参数: ptEmployeeInfo: 员工信息结构体

* 返回值: 0-成功  -1-失败

* 其它说明:无

* 修改日期          版本号           修改人         修改内容

* -----------------------------------------------------------------------------------

* 20140617           V1.0         Zhou Zhaoxiong      创建

***********************************************************************/

INT32 GetEmployeeInfo(TEmployeeInfo *ptEmployeeInfo)

{

// 先对输入的指针参数进行异常判断

if (ptEmployeeInfo == NULL)

{

printf("Input parameter is NULL.\n");

return -1;

}

strncpy((char *)ptEmployeeInfo->szEmployeeName, "Li Yuanfang", strlen("Li Yuanfang"));   // 对姓名字段赋值

ptEmployeeInfo->iEmployeeAge = 100;       // 对年龄字段赋值

ptEmployeeInfo->iEmployeeNo  = 123456;    // 对工号字段赋值

return 0;     // 赋值成功, 返回0

}

程序的运行结果如图2所示:

图2 改进后的采用指针传递时的程序代码运行结果

可见,程序出现了内存问题。原因是在传递之前,ptEmployeeInfo指针已经指向了确定的地址,不能让同一个指针同时指向不同的地址。

四、第二次改进后的程序代码

既然不能用指针作为参数进行传递,那么我们就要考虑另外的方法。

以下代码采用非指针的传递方式:

/**********************************************************************

* 版权所有 (C)2014, Zhou Zhaoxiong。

*

* 文件名称: TestStruct.c

* 文件标识:无

* 内容摘要:用于演示结构体变量的用法

* 其它说明:无

* 当前版本: V1.0

* 作    者:周兆熊

* 完成日期: 20140617

*

* 修改记录1:// 修改历史记录, 包括修改日期、版本号、修改人及修改内容

* 修改日期: 20140617

* 版本号: V1.0

* 修改人: Zhou Zhaoxiong

* 修改内容:创建

**********************************************************************/

#include <stdio.h>

#include <string.h>

// 数据类型

typedef signed   char INT8;

typedef unsigned char UINT16;

typedef unsigned int  UINT32;

typedef signed   int  INT32;

// 员工信息结构体

typedef struct

{

INT8    szEmployeeName[100];  // 员工姓名

UINT16  iEmployeeAge;         // 员工年龄

UINT32  iEmployeeNo;          // 员工工号

} TEmployeeInfo;

// 函数声明

INT32 GetEmployeeInfo(TEmployeeInfo *ptEmployeeInfo); // 获取员工信息函数

INT32 main(void);

/****************************************************************

* 功能描述:  主函数

* 输入参数:  无

* 输出参数:  无

* 返回值: 0-执行成功  -1-执行失败

* 其他说明:  无

* 修改日期        版本号        修改人        修改内容

* --------------------------------------------------------------

* 20140617        V1.0      Zhou Zhaoxiong     创建

****************************************************************/

INT32 main(void)

{

INT32         iRetValue     = 0;      // 该变量用于表示调用GetEmployeeInfo函数返回的值

TEmployeeInfo tEmployeeInfo = {0};    // 该变量用于存放员工信息

// 调用函数对员工信息字段赋值, 并打印出来

iRetValue = GetEmployeeInfo(&tEmployeeInfo);

if (iRetValue != 0)

{

printf("exec GetEmployeeInfo failed.\n");

return -1;

}

printf("员工信息为: \n姓名: %s\n年龄: %d\n工号: %d\n", tEmployeeInfo.szEmployeeName, tEmployeeInfo.iEmployeeAge, tEmployeeInfo.iEmployeeNo);

return 0;

}

/**********************************************************************

* 功能描述:对员工信息字段赋值

* 输入参数: ptEmployeeInfo: 员工信息结构体

* 输出参数: ptEmployeeInfo: 员工信息结构体

* 返回值: 0-成功  -1-失败

* 其它说明:无

* 修改日期          版本号           修改人         修改内容

* --------------------------------------------------------------

* 20140617           V1.0         Zhou Zhaoxiong      创建

***********************************************************************/

INT32 GetEmployeeInfo(TEmployeeInfo *ptEmployeeInfo)

{

// 先对输入的指针参数进行异常判断

if (ptEmployeeInfo == NULL)

{

printf("Input parameter is NULL.\n");

return -1;

}

strncpy((char *)ptEmployeeInfo->szEmployeeName, "Li Yuanfang", strlen("Li Yuanfang"));   // 对姓名字段赋值

ptEmployeeInfo->iEmployeeAge = 100;       // 对年龄字段赋值

ptEmployeeInfo->iEmployeeNo  = 123456;    // 对工号字段赋值

return 0;     // 赋值成功, 返回0

}

程序的执行结果如图3所示:

图3第二次改进后的程序代码执行结果

从图3可以看出,程序执行结果正确,得到了我们想要的结果。

五、总结

在编写代码的过程中,我们需要注意以下方面:

(1) 程序头部、函数头部及重要的程序语句处一定要有注释,这体现了软件开发人员的专业素养。

(2) 函数中出现的变量在定义的同时要进行初始化,函数在调用之前一定要先进行声明。

(3) 对于函数中的指针变量参数,在使用之前一定要先进行异常判断(即判断其是否为NULL)。

(4) 对于有返回值的函数,要用不同的返回值来区别不同的执行结果,并在重要的地方打印出提示信息,方便对代码的调试。

指针是C语言的精华所在,同时也是难点所在。对于一个合格的软件开发工程师来说,一定要熟练掌握指针的使用方法。

转载于:https://blog.51cto.com/9409270/1946424

C语言中结构体参数变量的传递相关推荐

  1. C语言中结构体成员变量前的点的作用

    /*  * 结构体中成员变量前的点: 结构体成员指定初始化  * 1.该结构体要先定义   * 2.一个成员变量赋值完后用逗号而不是分号   * 3.初始化语句的元素以固定的顺序出现,和被初始化的数组 ...

  2. c语言中申请内存并初始化,c语言中结构体的定义、初始化及内存分配

    #include struct person { char *name; int age; }; int main() { //结构体可以定义在函数内,也可以定义到函数外 //相当于全局变量与局部变量 ...

  3. c语言结构体成员变量私有化,C语言中结构体变量私有化详解

    C语言中结构体变量私有化详解 背景介绍 操作系统 : CentOS7.3.1611_x64 gcc版本 :4.8.5 什么是结构体? 在C语言中,结构体(struct)指的是一种数据结构,是C语言中聚 ...

  4. Go语言中结构体打Tag是什么意思?

    前言 哈喽,大家好,我是asong.今天想与大家分享Go语言中结构体标签是怎么使用的,以及怎样定制自己的结构体标签解析. 大多数初学者在看公司的项目代码时,看到的一些结构体定义会是这样的: type ...

  5. Go语言中结构体打 Tag 是什么意思?

    前言 哈喽,大家好,我是asong.今天想与大家分享Go语言中结构体标签是怎么使用的,以及怎样定制自己的结构体标签解析. 大多数初学者在看公司的项目代码时,看到的一些结构体定义会是这样的: type ...

  6. java发送c语言结构体_C语言中结构体直接赋值?

    在C语言中结构体变量之间可以进行赋值操作吗? 简单结构体的赋值 先说结论:一般来说,C语言中的结构体变量可以用另一个变量对其进行赋值或初始化.简单结构体(不包含指针成员)直接赋值没有问题. 我们先下面 ...

  7. c语言定义学生结构体类型,C语言中结构体的三种定义方式

    c语言中结构体的定义: struct 结构体名{ 成员列表: ..... }结构体变量: 7.1.1 结构体类型变量的定义 结构体类型变量的定义与其它类型的变量的定义是一样的,但由于结构体类型需要针对 ...

  8. C语言中结构体直接赋值

    FROM:http://codewenda.com/c语言结构体直接赋值/ 在C语言中结构体变量之间可以进行赋值操作吗? 简单结构体的赋值 先说结论:一般来说,C语言中的结构体变量可以用另一个变量对其 ...

  9. C语言中结构体标签的使用

    C语言中结构体标签的使用 我们都知道,结构体标签就是结构体的名称,为结构体命名可以方便我们在后续继续使用该结构体. 如 struct student {char* name;int age; }str ...

最新文章

  1. tensorrt轻松部署高性能dnn推理_NVIDIA Triton推理服务器助力深度学习推理
  2. Windows中各类画面源的截取和合成方法总结
  3. php gtk中文介绍,PHP-GTK介绍及其应用_PHP教程
  4. Spring源码:AOP转文
  5. LeetCode 57. 插入区间(一次遍历)
  6. win主机上搭建php网站运行环境,Windows server 2008搭建php运行环境图文详解(php5.3)
  7. 匿名内部类----java
  8. 愿望满足系统 1020 分支与循环控制
  9. Eclipse和PyDev搭建完美Python开发环境(Windows篇)
  10. @MapperScan扫描包的问题
  11. 力扣491. 递增子序列(JavaScript)
  12. CSND帐号居然又能用了,发个文章庆祝一下
  13. HTML5海报生成器源码,原生js小项目 - canvas海报生成器
  14. win10,ubuntu18.04系统下图像识别YOLOv5菠萝_附菠萝数据集图片标签
  15. [spark] spark推测式执行
  16. 苹果手机停用连接itunes_苹果手机密码输入次数过多停用怎么办?
  17. 关于客户端下载文件而不是在服务器生成文件
  18. web 页面 常用分辨率(PC 移动端)
  19. MacBook nice软件
  20. 一篇就可以搞定——ADB连接多台设备问题

热门文章

  1. [MySQL]增加用户 授权 远程登录
  2. APK签名导出向导 - Use the Export Wizard
  3. jQuery对select操作
  4. es6+最佳入门实践(10)
  5. JAVA设计模式初探之——装饰者模式
  6. 用Asp.net还原与恢复sqlserver数据库
  7. Delphi与JAVA互加解密AES算法
  8. JS面向对象高级特性
  9. 2016-2017-1 《信息安全系统设计基础》 学生博客及Git@OSC 链接
  10. 动效设计的物理法则:动画的一切皆在于时间点和空间幅度(转)