结构体的定义和初始化

结构体是简单数据类型的综合

struct man
{
char name[100];
int age;
};
struct man m = { "tom", 12 };
struct man m = { .name = "tom", .age = 12 };

访问结构体成员

要访问结构体成员,要使用.操作符。

m.age;

结构体的内存对齐模式

结构在内存的大小是和结构成员最长的那个元素相关的

编译器在编译一个结构的时候采用内存对齐模式

struct man{
char a;
int b;
};
//sizeof(struct man) = 8

指定结构体元素的位字段

定义一个结构体的时候可以指定具体元素的位长

struct test{
char a : 2;//指定元素为2位长,不是2个字节长
};

结构数组

struct man m[10] = { { "tom", 12 }, { "marry", 10 }, { "jack", 9 } };
m[1].name;

嵌套结构

一个结构的成员还可以是另一个结构类型

struct names{
char first[100];
char last[100];
}; struct man{
struct names name;
int age;
}; struct man m = { { "wang", "wu" }, 20 }; m.name.fist;//嵌套的使用

结构体的赋值

struct name a = b;

结构的赋值其实就是两个结构内存的拷贝

memcpy(&a, &b, sizeof(b));

如果结构体成员有指针元素,那么就不能直接赋值,原因是会指向同一块内存,使用free的话会造成没有实际指向

struct man
{
int age;
char *name;
}; int main()
{
struct man m1;
m1.age = 10;
m1.name = malloc(10);
strcpy(m1.name, "jack");
struct man m2;
m2.age = 12;
m2.name = malloc(strlen(m1.name) + 1);
strcpy(m2.name, m1.name);
}

指向结构体的指针

struct man m;
struct man *p = &m;
(*p).age = 10;//为操作简单,加入了->操作符
p->age = 10;

结构中的数组成员和指针成员

一个结构中可以有数组成员,也可以有指针成员

如果是指针成员结构体成员在初始化和赋值的时候就需要提前为指针成员分配内存

struct man
{
char name[100];
int age;
};
struct man
{
char *name;
int age;
};

在堆中创建的结构体

如果结构体有指针类型成员,同时结构体在堆中创建,那么释放堆中的结构体之前需要提前释放结构体中的指针成员指向的内存

struct man
{
char *name;
int age;
};
struct man *s = malloc(sizeof(struct man) * 2);
s[0].name = malloc(10 * sizeof(char));
s[1].name = malloc(10 * sizeof(char));
struct student
{
int ID;
char *name;
int age;
}; int main()
{
struct student *sp = malloc(sizeof(struct student) * 10);
memset(sp, 0, sizeof(struct student) * 10);
for (int i = 0; i < 10; i++)
{
sp[i].ID = i;
sp[i].age = i;
char buf[1024] = { 0 };
scanf("%s", buf);
int len = strlen(buf);//得到用户输入字符串的长度
sp[i].name = malloc(len + 1);
sprintf(sp[i].name, "%s", buf);
} for (int i = 0; i < 10; i++)
{
printf("ID =%d, age = %d, name = %s\n", sp[i].ID, sp[i].age, sp[i].name);
} for (int i = 0; i < 10; i++)
{
free(sp[i].name);
} free(sp);
}

结构体作为函数参数

结构体作为函数参数,基本数据类型不会被改变,指针会被改变

func(struct student st)
{
st.age = 10;//原数值不会改变
strcpy(st.name, "zhang");//原数值会被改变
} func(st)

结构指针作为函数参数,所有数据可改变

func(struct student *st)
{
st->age = 10;//原数值不会改变
strcpy(st->name, "zhang");//原数值会被改变
} func(&st)

其根本原因是指向问题

如果一个结构体变量做为函数的参数,效率极低。同时老的C编译器都不支持传递结构变量,只支持传递结构指针

结构体指针做函数返回值

可以返回结构体,但一般不那么做,原因是结构体返回太大

struct str *getstr()
{
struct str *s = malloc(sizeof(struct str));
strcpy(s->buf, "hello world");
return s;
}

C学习笔记-结构体的更多相关文章

  1. c语言学习笔记 - 结构体位域

    在学习结构体的时候遇到了位域这个概念,位域主要是为了节省内存空间,比如用一个32位,4个字节的int存储一个开关变量时,会造成空间浪费,于是干脆就考虑在这个32划分不同的区域来存储数据,例如划出1位存 ...

  2. C语言学习笔记--结构体

    结构体定义三种方式: #include<stdio.h> //第一种定义方法 struct point { int x; int y; }; struct point p1,p2; //第 ...

  3. go学习笔记-结构体

    结构体 结构体是由一系列具有相同类型或不同类型的数据构成的数据集合 定义 格式 type struct_variable_type struct { member definition; member ...

  4. C学习笔记-结构体与二进制文件增删改查

    使用结构体整理数据,然后利用二进制存储文件,这样存储的文件类似于数据库,可以实现文件的增删改查 定义结构体 struct student { unsigned int ID; char name[20 ...

  5. AngularJS1.X学习笔记1-整体看看

    听说 明天是愚人节,这与我有什么关系呢!我可 不想被愚弄,但是但是,我这么笨怎么才能不被愚弄呢?左思右想,我决定从现在开始闭关,闭关干啥哩?学习!学习AngularJS.以前学习过Angular的,不 ...

  6. Go笔记-结构体

    [定义] type identifier struct{ field1 type1 field2 type2 ... } // 声明 var s identifier identifier.field ...

  7. C语言学习之结构体

    前言 一直以来,C语言的学习都在入门阶段,只用到数组.函数.循环.选择.位运算这些基本的知识,较少用到指针.预处理.结构体.枚举类型.文件操作等这些C语言的精髓内容,现在想想真不敢说自己熟练掌握C语言 ...

  8. 瘋子C语言笔记(结构体/共用体/枚举篇)

    (一)结构体类型 1.简介: 例: struct date { int month; int day; int year; }; struct student { int num; char name ...

  9. C语言学习1——结构体剖析

    一、定义结构体变量的方法 1.1先声明结构体类型在定义变量名 例如: a.声明结构体类型 struct student { int num; char name[20]; char sex; int ...

随机推荐

  1. JavaScript算术运算符

    ㈠运算符(操作符) ⑴通过运算符可以对一个或多个值进行运算,并获取运算结果 ⑵比如:typeof就是运算符,可以来获得一个值得类型               它会将该值的类型以字符串的形式返回   ...

  2. ValseWebninar 报告汇总

    ValseWebninar为计算机视觉.图像处理.模式识别与机器学习等研究领域内的华人青年学者提供深入学术交流的舞台. 20191218:基于视觉和常识的深度推理  主持人:    主讲人: 2019 ...

  3. Fire Game (FZU 2150)(BFS)

    题解:一开始想错了,以为只要烧完就是那个答案,但是这不是最优的结果,需要每两个点都bfs一遍,找到如果能够全部烧完,找到花费时间最小的,如果不能return -1.在bfs的时候,记录答案的方法参考了 ...

  4. 使用matplotlib绘制常用图表(2)-常用图标设置

    一.使用subplots绘制子图 import numpy as np from matplotlib import pyplot as plt %matplotlib inline x = np.a ...

  5. AcWing:165. 小猫爬山(dfs + 剪枝)

    翰翰和达达饲养了N只小猫,这天,小猫们要去爬山. 经历了千辛万苦,小猫们终于爬上了山顶,但是疲倦的它们再也不想徒步走下山了(呜咕>_<). 翰翰和达达只好花钱让它们坐索道下山. 索道上的缆 ...

  6. linux shell 值coredump suid_dumpable和 gdb解析coredump文件

    可以设置产生coredump文件,设置dump文件命名非格式,生成dump文件的路径: linux # set suid_dumpable on if [ -e /proc/sys/kernel/su ...

  7. 化学结构SDF文件

    参考博客 第一行:一般作为分子名字,如 Levetiracetam 第二行:注释,ChemDraw06111413562D 第三行:一般是空行 第四行:是原子个数 键的个数等的起始行. M END所在 ...

  8. TCP层close系统调用的实现分析

    在调用close系统调用关闭套接字时,如果套接字引用计数已经归零,则需继续向上层调用其close实现,tcp为tcp_close:本文仅介绍tcp部分,前置部分请参考本博关于close系统调用的文章: ...

  9. D建立app项目(mui)

    参考 http://dev.dcloud.net.cn/mui/getting-started/ 1.ios需要下载iTunes,确保手机能连上电脑 2.mui可参考手册 http://dev.dcl ...

  10. 尚学堂requireJs课程---2、模块

    尚学堂requireJs课程---2.模块 一.总结 一句话总结: # 将代码以及使用放到独立的闭包中去,并且赋值给了变量,便于外部访问 # return出了函数和变量(放在一个json对象中) # ...