结构体
声明结构体时,并不会占用内存空间,只有当定义结构体变量时,才会分配内存空间。结构体的大小是所有成员大小之和。
结构体指针 = 结构体的指针,指向结构体变量的指针,这个指针指向的地址存储一个结构体类型
//定义结构体方式1,这种方式后续定义结构体变量时还需要使用struct Node XX;
struct Node{
int date;
Node* next;
};
//定义结构体方式2,使用这种方式后续定义结构体直接NodeName XX,相当于给结构体起别名
typedef struct Node{
int date;
Node* next;
}NodeStr;
//结构体指针
struct Node *strc1;
NodeStr *strc2;
链表
结构体成员是字符数组
#include <stdio.h>
#include <stdlib.h>
//结构体成员的定义时不能初始化
struct A{
//define char array
char strA[20];
int age;
char strB[20]; //内部成员是指针时,使用结构体前必须先给成员分配内存空间
}; //定义结构体时结尾的 ; 不能忘记
struct B{
struct A sbA;
int weight;
};
//结构体是普通结构体时,直接使用 <结构体.成员> 访问内部成员。若内部成员是指针时,使用结构体前必须先给成员分配内存空间,否则会造成段错误,有内存溢出造成。
//结构体成员是字符串/字符数组/字符指针时,使用scanf 输入时,使用 <结构体.成员>即可,此时成员就是指针,不再需要&。若成员是 实型数据时 scanf输入 必须使用 &。
//结构体指针:此时该指针指向一个结构体,使用该指针时必须初始化,将其指向一个结构体或NULL。
//结构体数组:使用指针指向结构体数组时,该指针的是数组第一个元素的地址。
int main(){
//定义结构变量
struct A sb, sa, *psa, *psb;
//结构体数组初始化的时候,可以写成 数组名[] = {{},{},{}}的形式,后续赋值时不能直接使用数组名[] = {} 的形式,只能对结构体成员循环赋值。
struct A sarray[3];//={{...},{...},{...}};
struct B ssb;
//后续结构体数组赋值
for(int i = 0; i < 3;i++){
sarray[i].weight = 90;
sarray[i].sbA.xx = xx;
}
psa = NULL;
psb = NULL;
psa = &sa;
psb = sarray;
//结构体是普通结构体时,直接使用 <结构体.成员> 访问内部成员.
//结构体成员是字符串/字符数组/字符指针时,使用scanf 输入时,使用 <结构体.成员> 即可
//此时成员就是指针,就是地址不再需要&。
//若结构体成员是实型数据时,使用scanf 必须使用 &
printf("普通结构体\n");
scanf("%s %d %s", sa.strA, &sa.age,sa.strB);
printf("普通结构体:\t%s\t%d\t%s\n",sa.strA,sa.age,sa.strB);
printf("结构体指针\n");
scanf("%s %d %s",psa->strA, &psa->age,psa->strB);
printf("结构体指针:\t%s\t%d\t%s\n",psa->strA, psa->age, psa->strB);
printf("结构体数组\n");
for(int i = 0; i < 2;i++){
printf("输入第%d个结构体数组\n",i+1);
scanf("%s %d %s", psb->strA, &psb->age,psb->strB);
printf("结构体Array:\t%s\t%d\t%s\n",psb->strA,psb->age,psb->strB);
psb++;
}
printf("嵌套结构体\n");
printf("name\tage\tclass\tweigth\n");
scanf("%s %d %s %d",ssb.sbA.strA, &ssb.sbA.age, ssb.sbA.strB, &ssb.weight);
printf("internal struct:\t%s\t%d\t%s\t%d\n",ssb.sbA.strA, ssb.sbA.age, ssb.sbA.strB, ssb.weight);
return 0;
}