结构体


结构体,就是一种自定义的数据类型。
说是数据类型,意思就是,跟其他的基本数据类型一样,可以像基本数据类型一样,定义变量。
例如:
与int i = 20;一样,我们如果自定义了一个结构体,名字叫做student,那么意思就是,我们有一个student类型,可以定义一个student类型的变量:student s = {…..}; 
结构体的声明:
struct student{
    char name[20];
    int age;
}; 

如上面的例子所说的,我们用结构体的关键字:struct 来规定 student 类型,花括号里是student类型的成员变量,这些变量都是基本数据类型修饰的变量,可以是普通变量,可以是数组。
注意的是:成员变量不能赋初值。(可以这样想,一个数据类型,怎么能给值?)
一些例子:


#import <Foundation/Foundation.h>
//这个时候,我们已经自定义好了一个CPoint类型
//这只是个类型,没有初值

struct CPoint{
    
    //不能赋初值,会报错
//    float x = 0;
//    float y = 0;
    //成员变量
    float x;
    float y;
    
    
};//结构体后面有分号,不能丢掉。
int main(int argc, const char * 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, const char * 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, const char * 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
typedef float  money;
//int类型定义成 height
typedef int height;
//用两种方式
//struct student 定义成student
//1.
typedef struct Student student;
//2.
typedef struct stu{
    char name[20];
    int age;

}Stu;
//struct Cpoint 定义成Cpoint
//1.
typedef struct  CPoint cpoint;
//2.
typedef struct CPoi {
    float x;
    float y;

}cpoi;
int main(int argc, const char * 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 北京

//点的结构体
typedef struct cpoint{
    float x;
    float y;
    
}cpoint;
//尺寸结构体
typedef struct csize{
    
    float w;
    float h;
    
}csize;
//矩形结构体
//结构体嵌套:结构体里有结构体
typedef struct cRect{
    cpoint point;
    csize size;
    
    
}cRect ;

//练习

typedef struct Student{
    
    int score;
    char name[20];

}Student;

int main(int argc, const char * 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, const char * argv[])
{
    //第一题
    //创建三个学生
    struct student student1 = {"五娃",17,88};
    
    struct student student2 = {"六娃",16,70};
    
    struct student 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;
}

 

posted @ 2016-05-09 19:47  胡一波  阅读(213)  评论(0编辑  收藏  举报