一、基本数据类型
1.int
1> long int、long:8个字节 %ld
2> short int、short:2个字节 %d %i
3> unsigned int、unsigned:4个字节 %zd
4> signed int、signed、int:4个字节 %d %i
2.float\double
1> float :4个字节 %f
2> double:8个字节 %f
3.char
1> 1个字节 %c %d
2> char类型保存在内存中的是它的ASCII值
'A' --> 65
二、构造类型
1.数组
1> 只能由同一种类型的数据组成
2> 定义:数据类型 数组名[元素个数];
2.结构体
1> 可以由不同类型的数据组成
2> 先定义类型,再利用类型定义变量
三、指针类型
1.变量的定义
int *p;
2.间接操作变量的值
int a = 10;
p = &a;
*p = 20;
四、枚举类型
使用场合:当一个变量只允许有几个固定取值时
变量的作用域
根据变量的作用域可以分为
- 全局变量
- 定义:在函数外面定义的变量
- 作用域:从定义变量的那一行开始,一直到文件结尾(能被后面的所有函数共享)
- 生命周期:程序一启动就会分配存储空间,程序退出时才会被销毁
- 默认的从初始值是0
- 局部变量
- 定义:在函数(代码块)内部定义的变量(包括函数形参)
- 作用域:从定义变量的那一行开始,一直到代码块结束
- 生命周期:从定义变量的那一行开始分配存储空间,代码块结束后就会被回收
- 没有固定的初始值
#include
int age;
void test()
{
int age;
age = 10;
}
int main()
{
printf("%d\n", age);// 0
int age = 20;
printf("%d\n", age);// 20
test();
printf("%d\n", age);// 20
return 0;
}
结构体
定义结构体的方法步骤
// 1.定义结构体类型(并不会分配存储空间)
struct Person
{ // 里面的3个变量,可以称为是结构体的成员或者属性
int age; // 年龄
double height; // 身高
char *name; // 姓名
};
// 2.根据结构体类型,定义结构体变量(真正分配存储空间)
struct Person p = {20, 1.55, "jack"};
/*
数组:只能由多个相同类型的数据构成
结构体:可以由多个不同类型的数据构成
*/
#include
int main()
{
// 1.定义结构体类型
struct Person
{ // 里面的3个变量,可以称为是结构体的成员或者属性
int age; // 年龄
double height; // 身高
char *name; // 姓名
};
// 2.根据结构体类型,定义结构体变量
struct Person p = {20, 1.55, "jack"};
p.age = 30;
p.name = "rose";
printf("age=%d, name=%s, height=%f\n", p.age, p.name, p.height);
/* 错误写法
struct Person p2;
p2 = {30, 1.67, "jake"};
*/
//一般情况下赋值操作的时候是按照定义的顺序依次赋值,如果不想按照顺序就需要用下面的两种方法进行赋值操作
//方法1
struct Person p2 = {.height = 1.78, .name="jim", .age=30};
//方法2
p2.name = "jim";
p2.height = 1.78;
p2.age = 25;
return 0;
}
注意事项
结构体的内存分配遵循对齐算法,也就是说结构体所占用的存储空间 必须是 最大成员字节数的倍数
struct Student
{
int age;// 4个字节
char *name; // 8个字节
};
struct Student stu;
//因为char*占8字节,根据对齐算法,下面的s输出 16 = 8*2 字节
int s = sizeof(stu);
结构体的三种定义方式
- 先定义类型在定义变量
// 1.类型
struct Student
{
int age;
double height;
char *name;
};
// 2.变量
struct Student stu = {20, 1.78, "jack"};
- 定义类型的同时定义变量
// 下面这句代码做了两件事情,1定义结构体类型2利用新定义好的类型来定义结构体变量
struct Student
{
int age;
double height;
char *name;
} stu;
- 定义结构体变量的第3种方式,匿名定义
struct {
int age;
char *name;
} stu;
结构体类型的作用域
- 定义在函数外面:全局有效(从定义类型的那行开始,一直到文件结尾)
- 定义在函数(代码块)内部:局部有效(从定义类型的那行开始,一直到代码块结束)
结构体数组
struct RankRecord
{
int no; // 序号 4
int score; // 积分 4
char *name; // 名称 8
};
/*
struct RankRecord r1 = {1, "jack", 5000};
struct RankRecord r2 = {2, "jim", 500};
struct RankRecord r3 = {3, "jake",300};
*/
struct RankRecord records[3] =
{
{1, "jack", 5000},
{2, "jim", 500},
{3, "jake",300}
};
records[0].no = 4;
// 错误写法
//records[0] = {4, "rose", 9000};
指向结构体的指针
/*
1.指向结构体的指针的定义
struct Student *p;
2.利用指针访问结构体的成员
1> (*p).成员名称
2> p->成员名称
*/
struct Student
{
int no;
int age;
};
// 结构体变量
struct Student stu = {1, 20};
// 指针变量p将来指向struct Student类型的数据
struct Student *p;
// 指针变量p指向了stu变量
p = &stu;
p->age = 30;
// 第一种方式
printf("age=%d, no=%d\n", stu.age, stu.no);
// 第二种方式
printf("age=%d, no=%d\n", (*p).age, (*p).no);
// 第三种方式
printf("age=%d, no=%d\n", p->age, p->no);
结构体和函数
#include
struct Student
{
int age;
int no;
};
// 如果结构体作为函数参数,只是将实参结构体所有成员的值对应地赋值给了形参结构体的所有成员
// 修改函数内部结构体的成员不会影响外面的实参结构体
void test(struct Student s)
{
s.age = 30;
s.no = 2;
}
// 会影响外面的实参结构体
void test2(struct Student *p)
{
p->age = 15;
p->no = 2;
}
void test3(struct Student *p)
{
struct Student stu2 = {15, 2};
p = &stu2;
p->age = 16;
p->no = 3;
}
int main()
{
struct Student stu = {28, 1};
//test(stu);
//test2(&stu);
test3(&stu);
printf("age=%d, no=%d\n", stu.age, stu.no);
return 0;
}
结构体的嵌套
#include
int main()
{
struct Date
{
int year;
int month;
int day;
};
// 类型
struct Student
{
int no; // 学号
struct Date birthday; // 生日
struct Date ruxueDate; // 入学日期
// 这种写法是错误的
//struct Student stu;
};
struct Student stu = {1, {2000, 9, 10}, {2012, 9, 10}};
printf("year=%d,month=%d,day=%d\n", stu.birthday.year, stu.birthday.month, stu.birthday.day);
return 0;
}