结构体
结构体,就是一种自定义的数据类型。
说是数据类型,意思就是,跟其他的基本数据类型一样,可以像基本数据类型一样,定义变量。
例如:
与int i = 20;一样,我们如果自定义了一个结构体,名字叫做student,那么意思就是,我们有一个student类型,可以定义一个student类型的变量:student s = {…..};
结构体的声明:
struct student{
charname[20];
intage;
};
如上面的例子所说的,我们用结构体的关键字:struct 来规定 student 类型,花括号里是student类型的成员变量,这些变量都是基本数据类型修饰的变量,可以是普通变量,可以是数组。
注意的是:成员变量不能赋初值。(可以这样想,一个数据类型,怎么能给值?)
一些例子:
#import <Foundation/Foundation.h> //这个时候,我们已经自定义好了一个CPoint类型 //这只是个类型,没有初值
struct CPoint{
//不能赋初值,会报错 // float x = 0; // float y = 0; //成员变量 float x; float y;
};//结构体后面有分号,不能丢掉。 int main(int argc,constchar * argv[]){
// //创建结构体变量,并按顺序赋值 // struct CPoint p = {1.5,2.5} ; // //打印结构体,得一个一个打印出来。 // printf("%f",p.x);//1.50000 // printf("%f",p.y);//2.50000 return 0; } |
结构体定义:
例子里已经声明了一个CPoint结构体类型,里边有两个成员变量:float型的x和y。我们在main()函数里,对CPoint结构体进行定义变量:
// //创建结构体变量,并按顺序赋值 struct结构体名变量名 = {初值}; // struct CPoint p = {1.5,2.5} ; |
注意:
初始化:开辟空间时,把值赋上,然后变量可以直接使用
赋值:开辟玩空间后,再往变量里赋值。但是不能对已经开辟好的结构体定义的变量里整个赋值。
//struct test{ // int num; //}; int main(int argc,constchar * argv[]){ // struct test t1 = {1}; // t1 = {222};//这里会报错 // return 0; } |
结构体的使用:
结构体的使用,通过我们定义的变量p来访问成员变量x和y。形式为:
p.x和p.y。
// //打印结构体,得一个一个打印出来。 // printf("%f",p.x);//1.50000 // printf("%f",p.y);//2.50000
|
一些练习:
#import <Foundation/Foundation.h> //这个时候,我们已经自定义好了一个CPoint类型 //这只是个类型,没有初值
struct CPoint{ //不能赋初值,会报错 // float x = 0; // float y = 0; //成员变量 float x; float y;
};//结构体后面有分号,不能丢掉。
//练习 //定义一个学生的结构体 struct Student {
short num;//学号 char name[20];//姓名 char sex;//性别 float score;//分数
}; //考虑定义一下结构体 //汽车 struct car { char brand[20]; int c_number ; int seats; float price; }; //人 struct person{
char name[20] ; char sex[4]; };
//电脑 struct computer{ char brand[20]; float price; char cpu[20]; int disk; };
//书 struct book { char bookName[20]; char isbn[50]; char publish[50]; char publishDate[20]; float price; }; int main(int argc,constchar * argv[]){
// //创建结构体变量,并按顺序赋值 // struct CPoint p = {1.5,2.5} ; // //打印结构体,得一个一个打印出来。 // printf("%f",p.x);//1.50000 // printf("%f",p.y);//2.50000
// struct Student s = {1,"王铁柱",'m',99}; // //同类型结构体之间可以直接赋值。 // struct Student s1 = s; // //吧s1的所有成员变量打印出来。 // printf("%d\n",s1.num); // printf("%s\n",s1.name); // printf("%c\n",s1.sex); // printf("%.1f\n",s1.score); // //不要把字符串赋值给字符变量(若写字符串,则要用字符数组) // struct person p1 = {"王大锤","男"}; // //结构体一旦创建好之后,字符数组成员变量不能再直接赋值了,需要使用strcpy(); p1.name = "田二牛";//报错 // strcpy(p1.name, "田二牛"); // printf("%s",p1.name); return 0; } |
创建的结构体变量,赋初值时,要按成员变量的顺序来赋初值。
相同类型的结构体,可以直接把另外一个结构体直接赋值给这个结构体。
若是再创建结构体时,成员变量需要用到字符串,则应该定义一个char型数组,而不能直接将字符串赋值给字符型变量。结构体一旦创建好之后,字符数组成员变量不能再直接赋值了,需要使用strcpy();
匿名结构体:
匿名结构体,没有名字,只能在定义结构体的时候,定义变量。如果再创建一个结构体的同时,没有定义结构体变量,那么这个匿名结构体就算一个没有用的结构体。
struct{ //成员变量 char name[20];
}p1 = {"刘哇"},p2 = {"小金刚"};//匿名结构体,再花括号后面配上一个结构体变量,并且可以直接定义多个变量,赋值。。 |
typedef:
typedef 这个关键字是为了一个已经有的类型重新取一个别名。
Typedef有两个作用:
1、提示一下,定义出来的变量是干什么用的。
typedef int age;//给int类型取别名age,提示这个类型是用来放年龄age的。
2、简化类型
typedef struct student student;//这个是告诉我们,将student这个类型取一个别名student。
简化结构体的类型有两种方法:
(1)、typedef struct student student;
(2)、一边定义我的结构体,一边同时简化我的类型。(作业:20遍)
typedef struct cat{
char color[20];
}Cat;
这种方式,是在声明cat结构体的同时,给它取了一个名字Cat。
简化类型有是好处呢?好处就是不用再在用struct这个关键字。
一些例子:
//练习
//float类型定义成money typedeffloat money; //int类型定义成 height typedefint height; //用两种方式 //struct student 定义成student //1. typedefstructStudent student; //2. typedefstruct stu{ char name[20]; int age;
}Stu; //struct Cpoint 定义成Cpoint //1. typedefstruct CPoint cpoint; //2. typedefstruct CPoi { float x; float y;
}cpoi; int main(int argc,constchar * argv[]){ //使用int的新名字定义变量 age num = 10; printf("%d",num);
//简化类型。不用再加上struct Person p2; //一边定义我的结构体,一边同时简化我的类型。 Cat c1 = {"白色"};
//练习 money money = 100; height h = 123;
student s = {}; Stu stu = {"王大锤",90};
cpoint cpoint = {1,2}; cpoi cpoi = {3,4};
return 0; } |
结构体内存占用:
结构体的内存占用情况,分为如下几点:
1、当结构体内没有定义任何成员变量时,这个结构体的占内存为0。
2、分配空间按照成员变量中,最大的分配。逐个使用。
3、内存对齐原则。(因此再定义结构体的时候,占内存大的放前面定义,然后逐个减小定义)
第3点说的明白点,就是结构体内定义一个类型变量时,会给这个类型分配固定字节的内存,但是当第二个成员变量的类型占内存更大时,这个第一个变量的内存会自动扩充到跟较大的那个内存一样。又因为,后一个变量类型在前一个变量的空间里,已经放不下,它不会接在前一个变量内存的后面,而是重新开辟一个内存,给自己用。当后面还有其他成员变量类型时,也不会接到这个变量内存的后面,而是重新开辟一个空间,用来放自己,但是开辟的空间还是跟最大的那个变量的类型占的字节一样大。因此如果在第三个变量后面还定义一个较小类型变量时,如果能在第三个变量的内存空间装完,则接在第三个变量内存后面,如果装不完,则开辟另一个空间。
例子:
结构体内,
先定义一个char 型变量(本身1字节),再定义一个double类型变量(本身8字节),则此时char类型空间开辟了8字节,由于double自己本身有8字节,接在char的后面不够装,因此它要开辟一个新的8字节内存。此时,再定义一个int类型的变量(本身4字节),此时会判断一下,再double那还能接下去装我的int吗?由于装不下,此时就会另外开辟一个8字节的内存空间来装int,还剩4个字节,如果再定义第4个char变量,则可以接到int类型的空间中去,还剩下3个字节。后面以此类推。
结构体的嵌套:
结构体的嵌套,就是结构体里有结构体。
例子如下:
#import <Foundation/Foundation.h>
//2015-04-03 16:17:15 北京
//点的结构体 typedefstruct cpoint{ float x; float y;
}cpoint; //尺寸结构体 typedefstruct csize{
float w; float h;
}csize; //矩形结构体 //结构体嵌套:结构体里有结构体 typedefstruct cRect{ cpoint point; csize size;
}cRect ;
//练习
typedefstruct Student{
int score; char name[20];
}Student;
int main(int argc,constchar * argv[]) { // //赋值 // cRect r = {{100,100},{50,50}}; // //使用 // printf("%.1f\n",r.point.x); // printf("%.1f\n",r.point.y); // printf("%.1f\n",r.size.h); // printf("%.1f\n",r.size.w);
// cpoint p1 = {10,20}; // cpoint p2 = {30,40}; // cpoint p3 = {50,60};
//结构体数组 //数组中所有元素,都已同一类型 // cpoint pointArray[3] = {p1,p2,p3};
// printf("%.2f\n",pointArray[0].x);
//练习 Student stu1 = {92,"王大锤1"}; Student stu2 = {91,"王大锤2"}; Student stu3 = {89,"王大锤3"}; Student stu4 = {99,"王大锤4"}; Student stu5 = {79,"王大锤5"};
//初始化:开开辟空间时,把值赋上,然后变量可以直接使用 //赋值:开辟玩空间后,再往变量里赋值。 //这两个过程是不一样的。
Student stuArr[5] = {stu1,stu2,stu3,stu4,stu5};
for (int i = 0; i < 5-1; i ++) { for (int j = 0; j < 5-(i+1); j++) { if(stuArr[j].score < stuArr[j+1].score){ Student temp; temp = stuArr[j] ; stuArr[j] = stuArr[j+1]; stuArr[j+1] = temp; } } } printf("成绩从高到低为:\n"); for (int i = 0; i < 5 ; i ++) { printf("%s: %d分\n",stuArr[i].name,stuArr[i].score); } printf("成绩最高的人为:%s:%d分",stuArr[0].name,stuArr[0].score);
return 0; }
|
结构体数组:
将多个结构体变量放到数组中,构成结构体数组。其实跟普通的数组一样,但是在遍历的时候,或者按照某个成员变量排序的时候,要注意的就是,比较有结果后,可以反回这个成员变量,也可以反回整个结构体,看个人方便,想要什么信息,就返回声明信息。
struct student students[10] = {0};
可以通过下标访问结构体变量,例如:
students[0].name; // 第⼀个学⽣的姓名
一些练习:
#import <Foundation/Foundation.h>
//2015-04-03 15:03:18 北京
//第一题
//1、创建学生结构体 //2、成员变量有:姓名,年龄,成绩 //3、五娃 17 88 // 六娃 16 70 // 七娃 9 75
//4、找出成绩最高 //5、找出年龄最小
struct student{
char stuname[20]; int age; int score;
}; //测试内存结构体 typedef struct Test{ //结构体内没有东西的时候,结构体占内存为0.
//结构体内存,有两条规则。 //1、分配空间按照成员变量中,最大的分配。逐个使用。 //2、内存对齐原则。(因此再定义结构体的时候,占内存大的放前面定义,然后逐个减小定义) }Test;
int main(int argc,constchar * argv[]) { //第一题 //创建三个学生 structstudent student1 = {"五娃",17,88};
structstudent student2 = {"六娃",16,70};
structstudent student3 = {"七娃",9,75};
// int maxScore = 0; // if (student2.score < student1.score && student3.score < student1.score) { // maxScore = student1.score; // printf("成绩最高的是:%s , %d分",student1.stuname,maxScore); // } // if (student1.score < student2.score && student3.score < student2.score) { // maxScore = student2.score; // printf("成绩最高的是:%s , %d分",student2.stuname,maxScore); // } // if (student1.score < student3.score && student2.score < student3.score) { // maxScore = student3.score; // printf("成绩最高的是:%s , %d分",student3.stuname,maxScore); // } // // int minAge =20; // // if (student2.age < student1.age && student2.age < student3.age) { // minAge = student2.age; // printf("\n年龄最小的是:%s , %d岁",student2.stuname,minAge); // } // if (student1.age < student2.age && student1.age < student3.age) { // minAge = student1.age; // printf("\n年龄最小的是:%s , %d岁",student2.stuname,minAge); // } // if (student3.age < student1.age && student3.age < student2.age) { // minAge = student3.age; // printf("\n年龄最小的是:%s , %d岁",student3.stuname,minAge); // }
//student1和 student2中分数最高 // struct student temp = student1.score > student2.score ? student1 : student2; // //temp和student3中分数最高 // struct student max = temp.score > student3.score ? temp : student3; // // printf("成绩最高的是:%s , %d分",max.stuname,max.score); // // // // struct student temp1 = student1.age < student2.age ? student1 : student2; // // struct student min = temp1.age < student3.age ? temp : student3; // // printf("\n年龄最小的是:%s , %d岁",min.stuname,min.age);
// //sizeof用来计算占内存多少字节。 // int size = sizeof(double); // printf("%d",size );//8 printf("%lu",sizeof(Test));
return 0; }
|