5.4.1 结构体类型是一种自定义类型
(1)C语言中的2种类型:原生类型和自定义类型。
5.4.2 结构体使用时先定义结构体类型再用类型定义变量
(1)结构体定义时需要先定义结构体类型,然后再用类型来定义变量。
(2)也可以在定义结构体类型的同时定义结构体变量。
#include <stdio.h>
//定义类型
struct people
{
char name[20];
int age;
} s1; //定义类型的同时定义变量
//将类型struct people 重命名为s1,s1是一个类型名,不是变量;
/*
typedef struct people
{
char name[20];
int age;
} s1;
*/
int main(void)
{
struct people p1;//使用结构体类型定义变量
s1.age = 23;
printf("s1.age = %d\n",s1.age);
struct people s2;
s2.age = 11;
printf("s2.age = %d\n",s2.age);
return 0;
}
5.4.3 从数组到结构体的进步之处
(1)结构体可以认为是从数组发展而来的。其实数组和结构体都算是数据结构的范畴了,数组就是最简单的数据结构、结构体比数组更复杂一些,链表、哈希表之类的比结构体又复杂一些;二叉树、图等又更复杂一些。
(2)数组有2个明显的缺陷:第一个是定义时必须明确给出大小,且这个大小在以后不能再更改;第二个是数组要求所有的元素的类型必须一致。更复杂的数据结构中就致力于解决数组的这两个缺陷。
(3)结构体是用来解决数组的第二个缺陷的,可以将结构体理解为一个其中元素类型可以不相同的数组。结构体完全可以取代数组,只是在数组可用的范围内数组比结构体更简单。
5.4.4 结构体变量中的元素如何访问?
(1)数组中元素的访问方式:表面上有2种方式(数组下标方式和指针方式);实质上都是指针方式访问;
(2)结构体变量中的元素访问方式:只有一种,用 . 或者 -> 的方式来访问。(.和->访问结构体元素其实质是一样的,只是C语言规定用结构体变量来访问元素用 . ,用结构体变量的指针来访问元素用 ->。实际上在高级语言中已经不区分了,都用 .)
(3)结构体的访问方式有点类似于数组下标的方式
思考:结构体变量的点号或者->访问元素的实质是什么?其实本质上还是用指针来访问的。
#include <stdio.h>
struct score
{
int a;
int b;
int c;
};
struct myStruct
{
int a;
double b;
char c;
};
int main(void)
{
struct myStruct s1;
s1.a = 12;
s1.b = 4.4;
s1.c = 'a';
//下标式访问
printf("s1.a = %d\n",s1.a);
printf("s1.b = %lf\n",s1.b);
printf("s1.c = %c\n",s1.c);
//结构体内部的元素之间地址都是相差8,难道是因为系统是64位系统?还是其它原因呢?
printf("&s1.a = %p\n",&s1.a);//&s1.a = 0x7ffc9ccd3b30
printf("&s1.b = %p\n",&s1.b);//&s1.b = 0x7ffc9ccd3b38
printf("&s1.c = %p\n",&s1.c);//&s1.c = 0x7ffc9ccd3b40
//指针式访问
int *p = (int *)&s1;
//这里为什么要将&s1强制类型转化为char *?
//当没有加强制类型转化时,&s1就表示整个结构体的地址,+8就表示
//加8个结构体本身所占的地址长度
double *p2 = (double *)((char *)&s1+8);
char *p3 = (char *)((char *)&s1+16);
printf("*p = %d\n",*p);
printf("*p2 = %lf\n",*p2);
printf("*p3 = %c\n",*p3);
/*
int a[3]; //3个学生的成绩,数组方式
score s; //3个学生的成绩,结构体方式
s.a = 11; //编译器在内部还是转成指针式访问int *p = (int *)&s; *(p+0) = 11
s.b = 12; //int *p = (int *)&s; *(p+1) = 12;
s.c = 13; //int *p = (int *)&s; *(p+2) = 13;
*/
return 0;
}