结构体
1,结构体定义
#include <stdio.h>
#include <string.h>
#define STUDENT struct person //本质是替换字符串
STUDENT { //结构体的作用域是从上往下,可以嵌套定义,不可以整体引用,只能单个引用成员变量
int num;
char name[30];
char sex;
int age;
char phone[20];
} stu1,stu2;
//STUDENT person 只是结构体类型,不分配内存,无法赋值
// stu1和stu2是结构体变量,分配内存,可以赋值,类似于基本类型的赋值
/*struct person{ //结构体的作用域是从上往下 此时的person就相当于基本类型中的int
int num;
char name[30];
char sex;
int age;
char phone[20];
}; //在声明的时候,不分配内存,各个元素之间分别占据不同的内存单元,连续,但互不影响
struct { //无名称的结构体变量,只有创建有限个结构体变量,只能定义时就获取变量,没有创建变量,就没有任何意义
int num;
char name[30];
char sex;
int age;
char phone[20];
}p1,p2,p3;
*/
void main(){
//初始化方式1
// struct person p; //在创建的时候,才分配内存空间
STUDENT p;
// p ={10, 这种大括号赋值的初始化方式错误,只能在创建的时候,一起初始化
// "luoxu",
// 'm',
// 18,
// "18041125454"};
p.num =10;
//p.name ="luoxu"; //字符串不能这样复制,可以采用以下两种方式赋值
strcpy(p.name,"luoxu");
sprintf(p.phone,"181044225255");
printf("%s\n",p.name);
printf("%s\n",p.phone);
p.sex='m';
p.age =18;
//初始化方式2
struct person p2 ={10,"luoxu",'m',18,"18041125454"};
//初始化3
struct { //无名称的结构体变量
int num;
char name[30];
char sex;
int age;
char phone[20];
}p3 ={10, //无名称的结构体变量初始化3
"luoxu",
'm',
18,
"18041125454"};
//初始化4 用另一个同类型的结构体变量初始化
struct person p4 =p2;
}
2、结构体嵌套
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
//结构体变量的嵌套定义
struct person{
int num;
char name[30];
struct student{
int num;
char name[23];
char course[30];
}; //此处只是内部定义了student类型,没有创建student类型的变量,外部将无法引用,可以采用下面的方式创建成员变量
struct student stu; //stu的等级和num,name,course一样
struct teacher{
int num;
char name[23];
char course[30];
}t1,t2; //t1,t2 的等级和stu,num,name,course一样
};
void main(){
struct person p;
p.stu.num = 100;
}
3、结构体数组
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
//结构体数组,每个元素都是结构体
struct person{
int num;
char name[20];
float money;
}p1[2] ={{1,"luoxu",100000.7},{2,"xiaoqing",100000.7}}; //第一种定义方式,有两个元素,每个元素都是地址
struct {
int num;
char name[30];
char phone[30];
}p2[2],p3[6]; //第二种匿名结构体的定义方式
void main(){
struct person p4[4]; //第三种定义方式
printf("%d,%d,%d\n", sizeof(int), sizeof(char [30]), sizeof(float)); //4,20,4 =28个字节
printf("%d,%d,%d\n", sizeof(p1), sizeof(p1[0]), sizeof(p1[1])); //56,28,28
printf("%x,%x,%x\n", &p1, &p1[0], &p1[1]); //403020,403020,40303c
// 对于p1[0],p1[1]来说,一个结构体person变量占用的字节数是(4+20+4)= 28
//&p1, &p1[0]是一样的,他们与&p1[1]相差28个字节(1C= 16+12)
//所以对于结构体数组来说,都是连续存储的
printf("%p,%p\n",p1[0],p1[2]); // 000000000061FD80,000000000061FD50
}
4、结构体指针
//结构体指针
struct person{
int num;
char name[20];
};
void main(){
//结构体的方式访问
struct person per;
per.num =100;
strcpy(per.name,"luoxu");
printf("per.num = %d,per.name = %s,",per.num,per.name);//per.num = 100,per.name = luoxu
//结构体指针的方式访问
struct person *p; //创建一个结构体指针变量,struct person 指明类型,从首地址往前读24个字节,以及如何解析
p = per; // 结构体名字代表结构体的首地址, p指向一个结构体,此时 (*p)= per;
printf("(*p).num = %d,(*p).name = %s,",(*p).num,(*p).name);//(*p).num = 100,(*p).name = luoxu
printf("p ->num = %d, p->name = %s,",p->num,p->name); //简化的方式 p ->num = 100, p->name = luoxu
//per.name <=> (*p).name <=> p->name
}
5、指向结构体数组的指针
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
//指向结构体数组的指针
struct person{
int num;
char name[20];
float money;
};
void main(){
struct person per[3] ={{1,"luoxu",1400004440.5},
{2,"xiaoqing",111004000.8},
{3,"xiaoqin",100000.7},
};
struct person *p;
p = per;
for (int i = 0 ; p < per+3, i < 3; ++p, ++i) { //p每次递增,加一个结构体的长度
printf("per.num = %d,per.name = %s\n,", per[i].num, per[i].name);//下标法
printf("(*p).num = %d,(*p).name = %s\n", (*p).num, (*p).name);//指针法
printf("p ->num = %d, p->name = %s\n", p->num, p->name); //指针法
}
}
6、用指向结构体的指针作函数参数
用结构体变量的成员作参数----值传递,新建副本
用指向结构体变量或数组的指针作参数----地址传递
用结构体变量作参数----多值传递,效率低,也是值传递
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
//用指向结构体的指针作函数参数
//用结构体变量的成员作参数----值传递,新建副本
//用指向结构体变量或数组的指针作参数----地址传递
//用结构体变量作参数----多值传递,效率低,也是值传递,新建副本
struct person{
int num;
char name[20];
float money;
};
void changeStruct(struct person p){ //结构体属于复杂基本数据类型,不是指针或数组,有副本机制,新建一个结构体变量p,存储per[0]传过来的“值”
// p.name = "Jobs"; 错误,字符串不能这样赋值
strcpy(p.name,"Jobs");
printf("p.num = %d,p.name = %s\n,", p.num, p.name); //p.num = 1,p.name = Jobs 改变成功
}
void changeStructPointer(struct person *p){
strcpy(p->name,"Jobs");
printf("p->num = %d,p->name = %s\n,", p->num, p->name); //p.num = 1,p.name = Jobs 改变成功
}
void main(){
struct person per[3] ={{1,"luoxu",1400004440.5},
{2,"xiaoqing",111004000.8},
{3,"xiaoqin",100000.7},
};
changeStruct(per[0]); //没有改变成功,
printf("per.num = %d,per.name = %s\n,", per[0].num, per[0].name); //per.num = 1,per.name = luoxu
changeStructPointer(&per[0]); //改变成功,
printf("per.num = %d,per.name = %s\n,", per[0].num, per[0].name); //per.num = 1,per.name = Jobs
}
7、内存动态分配
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
//内存动态分配
struct person{
int num;
char name[20];
float money;
};
void main(){
struct person *p = malloc(sizeof(struct person) * 10);
//数组下标法读写数组
for (int i = 0; i < 10; ++i) {
//写数据
p[i].num = i;
sprintf(p[i].name,"luoxu%d",i);
p[i].money = 1.1 *i;
//读数据
printf("p[%d].num = %d,p[%d].name = %s,p[%d].money = %f\n", i,p[i].num,i, p[i].name,i,p[i].money);
}
//数组下标 +i 法读写数组
for (int i = 0; i < 10; ++i) {
//写数据
(*(p+i)).num = i; //p[i] =(*(p+i))
sprintf((*(p+i)).name,"luoxu%d",i);
(*(p+i)).money = 1.1 *i;
//读数据
printf("p[%d].num = %d,p[%d].name = %s,p[%d].money = %f\n", i,(*(p+i)).num,i, (*(p+i)).name,i,(*(p+i)).money);
}
//指针法
for (int px = p, i =0 ; px < p+ 10, i < 10; ++p, i++) {
//写数据
(*p).num = i; //p->num
sprintf((*p).name,"luoxu%d",i);
(*p).money = 1.1 *i;
//读数据
printf("No.%d:(*p).num = %d,(*p).name = %s,(*p).money = %f\n", i,(*p).num,(*p).name,(*p).money);
}
}

浙公网安备 33010602011771号