结构体
用户自定义的一种数据类型
格式:
格式:struct 结构体名 结构体变量;
struct 结构体名
{
成员变量1;
成员变量2;
成员变量3;
};
1.定义结构体的同时,直接定义结构体变量
struct ABC
{
int id;
int age;
float height;
char name[33];
}abc; //全局变量
2.先定义结构体,再定义结构体变量
struct ABC
{
int id;
int age;
float height;
char name[33];
};
int main(int argc, char const *argv[])
{
struct ABC abc; //局部变量
return 0;
}
3.缺省结构体名
struct
{
int id;
int age;
float height;
char name[33];
}abc;
赋值
1.定义结构体同时,直接赋值
struct ABC
{
int id;
int age;
float height;
char name[33];
};
int main(int argc, char const *argv[])
{
struct ABC abc={1,2,3.3,"asd"}; //局部变量
return 0;
}
2.先定义,再去逐个赋值
#include<stdio.h>
struct ABC
{
int id;
int age;
float height;
char name[33];
}abc;
int main(int argc, char const *argv[])
{
abc.id=2;
abc.height=188.9;
return 0;
}
- 点等法
#include<stdio.h>
struct ABC
{
int id;
int age;
float height;
char name[33];
};
int main(int argc, char const *argv[])
{
struct ABC abc={
.id=2,
.age=11,
.height=156
};
return 0;
}
访问
通过:结构体变量名.成员变量名
printf(“%d %.1f\n”,ik.id,ik.height);
scanf(“%d %f %s”,&abc.id,&abc.height,abc.name);
重定义typedef
typedef int size_t; //将int类型更名为size_t
int a;====size_t a;
结构体的数据类型名字太长,重新取个别名;
typedef struct ABC
{
}KK;
即KK = =struct ABC
结构体数组
1.定义结构体的同时,定义结构体数组
struct star
{
int id;
int age;
float height;
char name[33];
}s[3];
- 先定义结构体,再定义结构体数组
struct star
{
int id;
int age;
float height;
char name[33];
};
int main(){
struct star a[3];
}
初始化
1.可以直接初始化
struct star
{
int id;
int a;
float h;
char name[33];
}s[2]={
{1,18,136,"abc"},
{2,22,123,"qwe"}
};
2.先定义结构体数组,再对数组的每一个元素进行赋值
struct star
{
int id;
int a;
float h;
char name[33];
};
int main()
{
struct star s[3];
for(int i=0;i<3;i++)
{
scanf("%d %d %f %s",&s[i].id,&s[i].a,&s[i].h,s[i].name);
}
}
注意结构体数组赋值时要加 & 字符数组本身赋字符串所以为地址不加
结构体指针
指向结构体变量的指针
格式:
struct结构体名 *结构体指针名
赋值
指针变量名->成员变量名
法1:p->id=5;
p->h=23.3;
strcpy(p->name,“abc”); //字符串赋值用strcpy
法2:(*p).id=6;
p代表地址,所以指针的操作也可用,(p+1)->id//表示结构体数组第二个内容数据的id
结构体大小
结构体内各数据存放形式:从低地址向高地址开辟空间。
1.按最大字节空间数据类型开辟,如图中所示最大为double(占8字节,但开辟空间为4字节,不是8字节),所以每次开辟要以4字节为单位
2.字节存放位置要为本身字节的整数倍,如double要存放在首地址为0,4,8…的位置,int要为0,4,8…的位置char就为0,1,2,3…位置。
3.存放顺序要按定义顺序,每次开辟空间按最大,如图中先开辟8个给double a,再开辟4个给char b,但第二次仅占用了一个字节,所以位置9开始空置,可以放置int c,不用再另外开辟新空间,但int只能存放在4的整数倍,所以从12开始存放。最后总空间字节大小为16
4.计算总的空间字节大小,如图sizeof(struct S);计算方法如3.
注意
- 在32位系统下,默认的value值为4字节,判断结构体中类型最大成员的字节大小,和默认的value值进行比较,按小的数进行对齐
- 结构体成员进行对齐时遵循地址偏移量是成员类型大小的整数倍,double类型数据存放在4字节的整数倍上(long long 也是4字节整数倍存储)
- 结构体成员按顺序进行存储
共用体
不同类型的成员变量共用一块地址空间
union共用体名
{
成员变量;
};
union共用体名 变量名;
特点:
- 成员变量共用同一块地址空间(存放位置相同)
- 成员变量赋值以最后一次为准
- 共用体的大小为成员变量中最大的为准
枚举
在实际编程中,有些数据的取值往往是有限的,只能是非常少量的整数,并且最好为每个值都取一个名字,以方便在后续代码中使用,比如一个星期只有七天,一年只有十二个月,一个班每周有六门课程等。
以每周七天为例,我们可以使用#define命令来给每天指定一个名字
格式:
enum枚举名
{
value1,
value 2,
value 3,
…
};
枚举的内部数据在未初始化时,根据最后一个初始化数据依次+1,都未初始化则从依次0开始+1
存储类型
如auto static
static修饰的变量会被存放在静态区
被static修饰的变量只初始化一次
生命周期为整个程序
修饰局部变量,和普通的局部变量作用域没区别,但是生命周期被延长至整个程序
修饰全局变量,限制在本文件使用
extern外部引用
可以引用其他文件中的全局变量和函数
例(linux下vs运行)
但运行时,要同时运行这两个文件