结构体

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);
    }
}

 

posted @ 2019-08-11 17:27  Coding_Changes_LIfe  阅读(214)  评论(0编辑  收藏  举报