一、变量类型
1.局部变量
1>定义:在函数(代码块)内部定义的变量
2>作用域:从定义变量的那一行开始,一直到代码块结束
3>生命周期:从定义变量的那一行开始分配存储空间,代码块结束后,就会被回收
4>没有固定的初始值
2.全局变量
1>定义:在函数外面定义的变量
2>作用域:从定义变量的那一行开始,一直到文件结尾(能被后面的所有函数共享)
3>生命周期:程序一启动就会分配存储空间,程序退出时才会被销毁
4>默认的初始值是0.
二、结构体
1、属于构造类型,可由不同的数据类型构成。
定义:
struct 结构体名称
{
};
定义变量:struct 结构体名称 变量名。
#include <stdio.h>
int main()
{
//自定义一个结构体
struct Person
{
//这三个变量可以称为结构体的成员或者属性
int age;
char *name;
double hight;
};
//定义一个结构体类型的变量,并初始化
struct Person p={21,"liming",45};
printf("age--%d\nname--%s\nhight--%0.2f\n",p.age,p.name,p.hight);
//声明和初始化分开
struct Person p1;
p1.age=34;
p1.name="lida";
p1.hight=56.7;
printf("age------%d\nname------%s\nhight---%0.2f\n",p1.age,p1.name,p1.hight);
//可以不按顺序赋值
struct Person p3={.name="liming",.age=45,.hight=65};
printf("age--%d\nname-----%s\nhight---%0.2f\n",p3.age,p3.name,p3.hight);
/*
struct Person p2;
p2={21,"liming",45};
这种初始化方式是错误的,大括号只能在声明的同时使用
*/
return 0;
}
2、结构体内存
(1)定义结构体时并不会分配存储空间
定义结构体类型的变量时才会分配存储空间
划分区域时,会从上到下依次按顺序划分
(2)结构体所占空间必须是最大成员字节数的倍数,这叫补齐算法或者对齐算法。
(3)p=p1,代表p1中的所有属性值对应的赋给p。
3、变量的多种定义方式
#include <stdio.h>
int main()
{
//自定义一个结构体的同时定义了一个结构体类型的变量
struct Person
{
int age;
char *name;
double hight;
}p1;
//定义一个结构体类型的变量,并初始化
struct Person p={21,"liming",45};
printf("age--%d\nname--%s\nhight--%0.2f\n",p1.age,p.name,p.hight);
//定义结构体且声明并初始化变量
struct Student
{
int age;
char *name;
}stu={.name="daming"};
printf("age--%d\nname--%s\n",stu.age,stu.name);
//匿名结构体,一般不常用
struct
{
char *name;
}book;
/*
struct Person
{
int age;
char *name;
double hight;
}p2;
这样是错误的,因为重复定义结构体。
*/
return 0;
}
4、结构体的作用范围
结构体的作用范围是从定义类型的那一行开始,一直到代码块结束。想要所有函数都能用,可以把这个结构体定义成全局变量。但依旧还是定义变量时才分配存储空间。
5、结构体数组
#include <stdio.h>
int main()
{
//定义一个学生结构体
struct Student
{
int age;
char *name;
double hight;
};
//定义一个结构体类型的数组
struct Student student[3]=
{
{23,"lisan",45.6},
{21,"liuxiao",40},
{20,"zhangsan",56}
};
//改变某个属性值
student[0].age=25;
//遍历
for(int i=0;i<3;i++)
{
printf("%d-%s-%0.2f\n",student[i].age,student[i].name,student[i].hight);
}
//结构体变量地址就是第一个属性地址
printf("%p\n%p\n",&student[0],&student[0].age);
/*
student[0]={23,"zhangsan",56};
这样是错误的
*/
return 0;
}
6、指向结构体的指针
#include <stdio.h>
int main()
{
//定义一个学生结构体
struct Student
{
int age;
char *name;
double hight;
};
//定义一个结构体类型的变量
struct Student student={23,"lisan",45.6};
//定义一个结构体类型的指针,变量p将来指向struct Student类型的数据
struct Student *p;
//p指向变量student
p=&student;
//访问结构体变量属性的三种方式
//第一种
student.age=89;
//第二种
(*p).name="黎明";
//第三种
p->hight=45.5;
printf("age--%d\nname--%s\nhight--%0.2f\n",p->age,student.name,(*p).hight);
return 0;
}
7、结构体与函数
如果结构体作为函数参数,只是将实参结构体所有成员的值对应的给了形参结构体的所有成员。修改函数内部结构体的成员不会影响外面的实参结构体。
#include <stdio.h>
struct St
{
int age;
};
void test(struct St s)
{
s.age=3;
}
void test1(struct St *p)
{
p->age=90;
}
void test2(struct St *p)
{
struct St st={233};
p=&st;
p->age=66;
}
int main()
{
struct St st={23};
//实参的值不会变
test(st);
printf("%d\n",st.age);
//因为是指针指向实参,所以值会变
test1(&st);
printf("%d\n",st.age);
//指针改变了指向,所以值不变
test2(&st);
printf("%d\n",st.age);
return 0;
}
8、结构体嵌套定义
注意:结构体不能自己包含自己
#include <stdio.h>
int main()
{
//日期
struct Date
{
int year;
int month;
int day;
};
//学生
struct Student
{
int age; //年龄
struct Date birthday; //生日
struct Date ruXueDate; //入学日期
};
//初始化变量
struct Student student=
{
25,{1990,3,2},{2004,9,1}
};
printf("生日是%d-%d-%d\n",student.birthday.year,student.birthday.month,student.birthday.day);
return 0;
}
三、枚举
1.定义
enum 枚举名 {枚举元素1,枚举元素2,……};
//跟结构体一样,有3种方式定义枚举变量
//1.先定义枚举类型,再定义枚举变量
enum Season {spring, summer, autumn, winter};
enum Season s;
//2.定义枚举类型的同时定义枚举变量
enum Season {spring, summer, autumn, winter} s;
//3.省略枚举名称,直接定义枚举变量
enum {spring, summer, autumn, winter} s;
注意:
1> C语言编译器会将枚举元素(spring、summer等)作为整型常量处理,称为枚举常量。2> 枚举元素的值取决于定义时各枚举元素排列的先后顺序。默认情况下,第一个枚举元素的值为0,第二个为1,依次顺序加1。
enum Season {spring, summer, autumn, winter};
也就是说spring的值为0,summer的值为1,autumn的值为2,winter的值为3
3> 也可以在定义枚举类型时改变枚举元素的值
enum season {spring, summer=3, autumn, winter};
没有指定值的枚举元素,其值为前一元素加1。也就说spring的值为0,summer的值为3,autumn的值为4,winter的值为5
//1.赋值
//可以给枚举变量赋枚举常量或者整型值
enum Season {spring, summer, autumn, winter} s;
s = spring; // 等价于 s = 0;
s = 3; // 等价于 s = winter;
//2.遍历枚举元素
enum Season {spring, summer, autumn, winter} s;
// 遍历枚举元素
for (s = spring; s <= winter; s++) {
printf("枚举元素:%d \n", s);
}