C语言数据类型非常丰富,其中结构体的使用非常广泛,也有一点复杂,这一讲我们主要学习结构体的使用方法,同时也会学习到联合、枚举以及typedef的使用,因为结构体最为复杂,使用最广,所以我们主要学习结构体。

struct结构体的定义和初始化

//例:
struct student{
char name[];
int age;
};
int main(){
struct student st;
//定义了一个student类型的结构体,名字叫做st,存放在栈里边
st.age =;
strcpy(st.name,”liudehua”);
struct student st1 ={“zhzdu”,};
//定义结构体变量,同时初始化结构体变量
struct student st1 ={.age =,.name=”zxjiifuhg”};
//定义结构体变量,同时初始化结构体变量,使用这种方式可以改变初始化顺序
struct student st1 ={“zhzdu”};
//定义结构体变量,同时初始化结构体变量,不初始化的结构体变量则默认为0
};

结构体的对齐说明

结构体在内存中总是对齐的,一个结构体成员变量总是以最大的那个元素作为对齐单位。

struct A{//8字节,a1后面空着3个字节,a2占4个字节
char a1;
int a2;
}
struct A1{//8字节,a1后面空着一个字节,然后a3占两个字节,a2占4个字节
char a1;
short a3;
int a2;
}
struct A2{
char a[];
int b;
}

如果结构体出现数组,则以数组中的具体每个成员大小为对齐标准,如果变量结构体中的所有成员都是一种类型,那么结构体在内存中就基本和一个数组类似。结构体变量的地址就是它首元素的地址。

结构体元素的位字段

      为了节省内存空间,结构体变量允许使用为声明,例子如下:

struct A2{//一共占1字节
unsigned char a:;//a只有两个bit
unsigned char b:; //b只有4个bit
}

结构体数组

struct A2{
char name[];
unsigned char age;
unsigned char sex;
}
void main(){
struct A2 st[];//定义一个结构体数组,有3个成员,每个成员都是struct结构体变量
}

CPU处理int相比其它基本数据类型效率是最高的,但是int比char要多占内存.

冒泡排序结构体数组

首先要学会使用冒泡排序,然后根据结构体某个成员大小之间作比较,再根据冒泡排序交换结构体中的各个成员来排序,具体的实现方法可自行实现。

结构体嵌套

结构体内部可以有其它结构体,其本质和结构体没有太多区别。

struct A{
char a1;
short a2;
}; struct B{
struct A a;//这里是一个结构体的嵌套
char a3;//上面结构体变量作为一个整体存在,a3 不可能补到结构体A a2的后面去,它一定是一个单独的对齐单位。
int b;
};
struct D{};//D结构体不含有任何结构体变量,这个语法在C语言是不合法的,在C++里是合法的

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

struct A{
char a1;
short a2;
};
struct A st1={s ,s};
struct A st2=st1;
//通过指针访问结构体成员
struct A * p=&st1;
//(*p).a1 =12;这种写法与下面写法作用相同,但下面写法更直观
p->a1 = ;

通过指针访问结构体数组

这个和通过指针去访问数组是类似的,这儿就不详细介绍了

void main(){
struct A2 st[]={};
struct A2 *p=st;
p[].name = “zcxc”
}

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

struct man{
char * name;
int age;
};

结构体拷贝的时候存在浅拷贝与深拷贝;浅拷贝之间只是成员之间的粗暴赋值,解决不了结构体中存在指针时,两个指针成员之间只是简单的地址赋值,当一个结构体变量指针成员释放空间时,另一个结构体变量指针成员访问的空间也就消失了,两结构体变量之间相互影响很大。深拷贝则是存在指针变量时,首先为指针变量各自分配空间,然后再进行拷贝,每个结构体指针变量指向的的空间时相互独立的。

堆中创建结构体变量

struct man{
char name[];
int age;
};
struct student{
char * name;
int age;
}
int main(){
struct man st;//name在栈里边
struct man *st1 = malloc(sizeof(struct man));//name在堆里边
struct man *p = malloc(sizeof(struct student));//name在堆里边
p->name = malloc();
strcpy(p->name,”lfsdi”);//申请一个堆空间,st1->name在堆里,但是一个野指针
st1->age = ;
free(p->name);
free(p);//如果结构体变量里含有指针,注意free的先后顺序,如果先free p,则p堆已经释放了,就找不到p->name的首地址
}

函数的参数为结构体变量

struct man{
char name[];
int age;
};
printf_student(struct student st){//st是形参,函数调用的时候,在栈里面有一个浅拷贝的过程,如果里边某个成员为数组较大,会出现一个数组拷贝的过程,会消耗大量时间,不利于优化程序
printf(“%s,%d\n”,st.name,st.age);
}
printf_student(const struct student *st) {//st =&st //只是一个简单的结构体地址赋值,效率远远高于上面的,形参很少直接用一个结构体变量,一般放结构体指针
printf(“%s,%d\n”,st->name,st->age);
}

联合体

联合union是一个能在同一个存储空间存储不同类型的数据,联合体所占的内存长度等于其最长成员的长度,所以代码效率很高。联合体虽然有多个成员,但同一时间只能存放其中一种。

union A{
int a1;
short a2;
char a3;
char *p;
};//只占4个字节
int main(){
union A a;
a1 =;
a3 =;
a1 =; //之后a.a3的值为0
a.p = malloc();//假设这块堆的内存编号为0x12345C
a.a1 = ;//p的值也成了0
free(a.p);
return ;
}

枚举类型

可以使用枚举声明代表整数常量的符号名称,关键字enum创建一个新的枚举类型,实际上enum常量是int类型的,可以增加代码的可读性。

struct A2{
char name[];
unsigned char age;
unsigned char sex;
} enum color{red,blue,yellow,green,black};
enum sex {man,woman};
void main(){
struct A2 st;
enum sex s;
s =man;
strcpy(st.name,”znfysry”);
st.sex = man;//man就是一个整形的常量,不能做左值,常量也不能取地址
st.age = ;
}

每一个枚举都有默认值0,1, 2,3,4,5,6……… 可以自己设置每个成员的值,enum color{red = 100,blue =12,red = 58,yellow,black,white};100,12,58,59,60,61.....,100 在系统内是由CPU产生的一个立即数,不能取地址, “hello”在内存的常量区里,可以取地址,int a =100;//CPU生成一个立即数,在栈中分配一个4个字节的空间,然后把这个空间的值设置为100,enum在编译完成后只是一个不存在于内存中的立即数,不能取地址。

typdef数据类型

typdef数据类型是一种高级数据类型,它能使某种类型创建自己的名字。仅限于数据类型,不能是表达式或具体的值。

struct student{
char name[];
unsigned char age;
unsigned char sex;
}
typedef struct student M;//M就类似于int,就是一种数据类型
typedef unsigned char BYTE;//多了一种数据类型叫byte.可以提高代码的维护性
int main(){
M m;
BYTE a;
return ;
}

typdef数据类型不是一种必须使用的数据类型,但是使用typedef主要目的是为了让程序的可读性更高,方便代码的维护,在代码十分庞大的时候这种数据类型就显得十分必要。

#ifndef UNICODE  //方便维护代码
typedef wchar_t TCHAR
#else
typedef char TCHAR
#endif
void main(){
TCHAR a1;
}

C语言复合数据类型的更多相关文章

  1. [日常] Go语言圣经--复合数据类型,数组习题

    go语言圣经-复合数据类型 1.以不同的方式组合基本类型可以构造出来的复合数据类型 2.四种类型——数组.slice.map和结构体 3.数组是由同构的元素组成——每个数组元素都是完全相同的类型——结 ...

  2. Verilog缺少一个复合数据类型,如C语言中的结构体

    https://mp.weixin.qq.com/s/_9UsgUQv-MfLe8nS938cfQ Verilog中的数据类型(Data Type)是分散的,缺少一个复合数据类型:把多个wire, r ...

  3. Go语言入门篇-复合数据类型

    复合数据类型 主要讨论四种类型——数组.slice.map和结构体 数组和结构体聚合类型   --数组和结构体都是有固定内存大小的数据结构 --数组:由同构的元素组成——每个数组元素都是完全相同的类型 ...

  4. C语言的数据类型及其对应变量

    声明,定义和初始化 声明标识符iden是告诉编译器"有这么一个变量var,具体var里是什么,你自己去看".声明只需要标识符的类型和标识符名字,C语言的任何标识符在使用前都需要声明 ...

  5. C/C++知识总结 五 复合数据类型 壹(数组、字符串与string、结构)

    C/C++复合数据类型 壹(数组.结构) 数组 数组的意义.定义与创建 一.二维数组应用 字符数组与字符串处理函数 数组与指针---关系密切 数组的意义与定义创建 意义:反映数据间的特点(通过把同一类 ...

  6. Chisel3 - 复合数据类型

    https://mp.weixin.qq.com/s/rXYqiZKuBpAYL8R94zxgRA   Chisel允许用户根据需要,把基本数据类型组合成为复合数据类型使用.如C语言里面的结构体,这样 ...

  7. 谈谈C语言的数据类型

    本文摘要: 本文主要讲述C语言中的数据类型,从基本的数据类型到派生的数据类型,从int ,char ,float double ....到指针,数组,函数,指向指针的指针,指向数组的指针,指向函数的指 ...

  8. C语言的数据类型

    复习之余,做点笔记<C语言之数据类型> 一.整数数据类型 (1)整数数据类型 整数类型 char 字符型变量   1字节(8Bit) short 短整型      2字节(16Bit) i ...

  9. C语言中数据类型的取值范围

    C语言中数据类型的取值范围如下:char -128 ~ +127 (1 Byte)short -32767 ~ + 32768 (2 Bytes)unsigned short 0 ~ 65536 (2 ...

随机推荐

  1. mongoDb 命令

    1.显示MongoDB的服务器统计:db.stats() 2.创建数据库:use dbname 3.删除数据库:db.dropDatabase() 4.检查当前选择的数据库:db 5.检查数据库列表: ...

  2. Python学习---线程锁/信号量/条件变量同步/线程池1221

    线程锁 问题现象: 多线程情况下,CPU遇到阻塞会进行线程的切换,所以导致执行了tmp-=1的值还未赋值给num=tmp,另一个线程2又开始了tmp -=1,所以导致最后的值重复赋值给了num,所以出 ...

  3. Android(java)学习笔记208:Android下的属性动画高级用法(Property Animation)

    1. 大家好,在上一篇文章当中,我们学习了Android属性动画的基本用法,当然也是最常用的一些用法,这些用法足以覆盖我们平时大多情况下的动画需求了.但是,正如上篇文章当中所说到的,属性动画对补间动画 ...

  4. JAVA中高访问量高并发的问题怎么解决?

    尽量使用缓存,包括用户缓存,信息缓存等,多花点内存来做缓存,可以大量减少与数据库的交互,提高性能. 用jprofiler等工具找出性能瓶颈,减少额外的开销. 优化数据库查询语句,减少直接使用hiber ...

  5. 四·安装mysql-5.7.16-linux-glibc2.5-x86_64.tar.gz(基于Centos7源码安装)

    1.在Linux中创建用户mysql和主目录,并创建密码 2.解压缩tar.gz并拷贝到/usr/local/mysql目录下面 3.把/usr/local/mysql文件夹拥有者改为mysql 进入 ...

  6. __call、__set 和 __get的用法

    1. __call的用法 PHP5 的对象新增了一个专用方法 __call(),这个方法用来监视一个对象中的其它方法.如果你试着调用一个对象中不存在的方法,__call 方法将会被自动调用. 例:__ ...

  7. 2018 Multi-University Training Contest 4 Problem L. Graph Theory Homework 【YY】

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6343 Problem L. Graph Theory Homework Time Limit: 2000 ...

  8. CVPR 2016 paper reading (6)

    1. Neuroaesthetics in fashion: modeling the perception of fashionability, Edgar Simo-Serra, Sanja Fi ...

  9. 数据元&数据字典&元数据

    1. 数据元 data element(数据元素),单个数据单元,是数据的基本单位.参阅data field(数据字段). 2. 元数据 首先,我们举个例子来看看什么叫做“元”,在后现代主义文学中有一 ...

  10. if __name__ == "__main__"如何正确理解

    粗略来讲,__name__是当前模块,当模块被直接运行时模块名为__main__.这句话的意思是,当模块被直接执行时,代码将运行,当模块是被导入时,代码不被运行 例如,执行one.py # file ...