深入理解C语言-结构体做函数参数
结构体做函数参数,在C语言中属于常见现象,此时为了内存考虑,不传递结构体,而是传递结构体的地址
结构体定义
struct Man
{
char name[64];
int age;
};
结构体可以与typedef结合使用
typedef struct _Man
{
char name[64];
int age;
}Man;
另外,可以直接定义结构体变量
typedef struct _Man
{
char name[64];
int age;
}Man1,Man2;
还可以采用匿名结构体变量
typedef struct
{
char name[64];
int age;
}Man1;
结构体指针
指向结构体的指针
Man tArray;
Man *pArray = NULL;
pArray = &tArray;
Man tArray[3];
Man *pArray = NULL;
pArray = tArray;
简单的结构体做函数参数
int printMan(Man *tArray, int num)
{
int i = 0;
for (i = 0; i < num; i++)
{
printf("%d \n", tArray[i].age);
}
return 0;
}
被调函数给结构体分配内存
当结构体的内存在被调函数中分配时,要将其传出,有两种方法
- 使用return传出
Man *createMan(int num)
{
Man *tArray = NULL;
tArray = (Man *)malloc(num * sizeof(Man));
if (tArray == NULL)
{
return NULL;
}
return tArray;
}
- 使用二级指针传出
int createMan(Man **tArray, int num)
{
(*tArray) = (Man *)malloc(num * sizeof(Man));
if (tArray == NULL)
{
return -1;
}
return 0;
}
createMan(&Man1, 3);
当结构体中存在指针
存在一级指针
typedef struct _Man
{
char name[64];
char *like;
int age;
}Man;
此时,要注意一点,要使用结构中的指针,就需要给其分配内存空间
Man *creatMan(int num)
{
int i = 0;
Man *tArray = NULL;
tArray = (Man *)malloc(num * sizeof(Man));
if (tArray == NULL)
{
return NULL;
}
for (i = 0; i < num; i++)
{
tArray[i].like = (char *)malloc(100);
}
return tArray;
}
Man *pArray = NULL;
pArray = crateMan(3);
存在二级指针
typedef struct _Man
{
char name[64];
char *like;
char **skill;
int age;
}Man;
此处和一级指针类似,必须分配其内存
Man *createMan(int num)
{
int i = 0, j = 0;
Man *tArray = NULL;
tArray = (Man *)malloc(num * sizeof(Man));
if (tArray == NULL)
{
return NULL;
}
for (i = 0; i < num; i++)
{
tArray[i].like = (char *)malloc(100);
}
for (i = 0; i < num; i++)
{
char **ptmp = (char **)malloc((4+1)*sizeof(char *));
for (j = 0; j < 4; j++)
{
ptmp[j] = (char *)malloc(120);
}
ptmp[4] = NULL;//分配5个空间,最后一个空间用来自我约束,相当于分配4个空间
tArray[i].skill = ptmp;
}
return tArray;
}
Man *pArray = NULL;
pArray = createMan(3);
if (pArray == NULL)
{
return ;
}
在使用完毕要释放内存,此时开辟了多少内存就要释放多少内存,从内层到外层依次释放
int FreeTArray(Man *tArray, int num)
{
int i = 0, j = 0;
if (tArray == NULL)
{
return -1;
}
for (i = 0; i < num; i++)
{
char **tmp = tArray[i].skill;
if (tmp ==NULL)
{
continue;;
}
for (j = 0; j < 3; j++)
{
if (tmp[j] != NULL)
{
free(tmp[j]);
}
}
free(tmp);
}
for (i = 0; i < 3; i++)
{
if (tArray[i].like != NULL)
{
free(tArray[i].like);
tArray[i].like = NULL;
}
}
free(tArray);
tArray = NULL;
}
求结构体成员的相对偏移量
int i = 0;
i = (int )&(((Man *)0)->age);
printf("i:%d \n", i);
其实是将首地址映射到0,求其偏移量
深入理解C语言-结构体做函数参数的更多相关文章
- go语言基础之结构体做函数参数 值传递和地址传递
1.结构体做函数参数值传递 示例: package main //必须有个main包 import "fmt" //定义一个结构体类型 type Student struct { ...
- go语言结构体作为函数参数,采用的是值传递
经过验证,go语言结构体作为函数参数,采用的是值传递.所以对于大型结构体传参,考虑到值传递的性能损耗,最好能采用指针传递. 验证代码: package main import ( "fmt& ...
- golang中结构体当做函数参数或函数返回值都会被拷贝
1. 结构体做函数的参数或返回值时,都会被重新拷贝一份如果不想拷贝,可以传递结构体指针 package main import "fmt" type Person struct { ...
- 【C++】结构体/结构体数组/结构体指针/结构体嵌套/函数参数/const
一.结构体声明 struct Student { //成员列表 string name; int age; int score; }; //s3;定义时直接声明 int main() { struct ...
- C语言结构体和函数
#include <stdio.h> struct Person { char *name; }; void change1(struct Person p); void change2( ...
- C语言中数组做函数参数的问题
数组做函数参数,会退化成为一个指针变量.因此在进行数组参数传递的同时,需要传递一个数组长度的参数变量. 数组长度可以通过sizeof(arr)/siezof(arr[0])来得到.关于这个sizeof ...
- C语言结构体及函数传递数组參数演示样例
注:makeSphere()函数返回Sphere结构体,main函数中.调用makeSphere()函数,传递的第一个參数为数组,传递的数组作为指针.
- C语言 结构体作为函数的参数
1)使用结构体变量作为函数的参数 使用结构体变量作为函数的实参时,采用的是值传递,会将结构体变量所占内存单元的内容全部顺序传递给形参,形参必须是同类型的结构体变量 demo: # include &l ...
- c语言结构体
[C语言]21-结构体 本文目录 一.什么是结构体 二.结构体的定义 三.结构体变量的定义 四.结构体的注意点 五.结构体的初始化 六.结构体的使用 七.结构体数组 八.结构体作为函数参数 九.指向结 ...
随机推荐
- mysql 密码重置或忘记密码相关命令
方法1: 用SET PASSWORD命令 首先登录MySQL. 格式:mysql> set password for 用户名@localhost = password('新密码'); 例子:my ...
- NPM全局安装软件包时解决EACCES权限错误
NPM全局安装软件包时解决EACCES权限错误 Resolving EACCES permissions errors when installing packages globally npm WA ...
- [Debug] Debugger Statements
For example you have the following code; function reverse(str) { let reversed = ""; for (l ...
- [AngularJS] Decorator pattern for code reuse
Imaging you have a large application, inside this large application you have many small individual a ...
- Crash的数字表格 / JZPTAB
https://www.cnblogs.com/peng-ym/p/8666124.html #include<bits/stdc++.h> #define LL long long #d ...
- ZOJ - 4114 Flipping Game
ZOJ - 4114 Flipping Game 题目大意:给出两个串s,t,n个灯泡的序列,1代表开着,0代表关着,一共操作k轮,每轮改变m个灯泡的状态,问最终能把s串变成t串的方案数. 坤神题解. ...
- 如何使用PHP排序key为字母+数字的数组
你还在为如何使用PHP排序字母+数字的数组而烦恼吗? 今天有个小伙伴在群里问: 如何将一个key为字母+数字的数组按升序排序呢? 举个例子: $test = [ 'n1' => 22423, ' ...
- 关于Math.random()
关于 Math.random() ,以前经常搞混淆,这次写个笔记专门记录下: Math.random() : 返回的是 0~1 之间的一个随机小数0<=r<1,即[0,1); 注意:这里 ...
- how to force git to overwritten local files
最佳解决方法 重要提示:如果您有任何本地更改,将会丢失.无论是否有--hard选项,任何未被推送的本地提交都将丢失. 如果您有任何未被Git跟踪的文件(例如上传的用户内容),这些文件将不会受到影响. ...
- useMemo、useCallback简单理解
1.useMemo.useCallback都是使参数(函数)不会因为其他不想关的参数变化而重新渲染. (1)useMemo const memoDom = useMemo(() => { ret ...