C語言 結構體

C語言 結構體

數組:描述一組具備相同類型數據的有序集合,用於處理大量相同類型的數據運算。

有時咱們須要將不一樣類型的數據組合成一個有機的總體,如:一個學生有學號/姓名/性別/年齡/地址等屬性。顯然單獨定義以上變量比較繁瑣,數據不便於管理。

C語言中給出了另外一種構造數據類型——結構體。 c++

結構體變量定義初始化

1、定義結構體變量的方式

  • 先聲明結構體類型再定義變量名
  • 在聲明類型的同時定義變量
  • 直接定義結構體類型變量(無類型名)

2、 結構體類型和結構體變量關係

  • 結構體類型:指定了一個結構體類型,它至關於一個模型,但其中並沒有具體數據,系統對之也不分配實際內存單元。
  • 結構體變量:系統根據結構體類型(內部成員情況)爲之分配空間。

3、結構體案例

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

// struct 結構體名
// {
// 結構體成員列表
//    姓名
//  年齡
//  成績
// };

struct student
{
    char name[21];
    int age;
    int score;
    char addr[51];
};
// 方式三
// 建立全局變量
// stu = { "張三",18,100,"北京市昌平區北清路22號" };

int main(void)
{
    // 方式一
    // 建立結構體變量
    // 結構體類型 名稱 結構體變量
    // struct student stu;
    // 數組結構體變量爲常量:不能直接複製stu.name = "張三"; 
    // 經過拷貝方式賦值變量
    // strcpy(stu.name, "張三");
    // stu.age = 18;
    // stu.score = 100;
    // strcpy(stu.addr, "北京市昌平區北清路22號");

    // 方式二
    struct student stu = { "張三",18,100,"北京市昌平區北清路22號" };

    printf("姓名:%s\n", stu.name);
    printf("年齡:%d\n", stu.age);
    printf("成績:%d\n", stu.score);
    printf("地址:%s\n", stu.addr);

    return 0;
}
結構體 使用案例:成員使用
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>


struct student
{
    char name[21];
    int age;
    int score;
    char addr[51];
};

int main(void)
{
    // 經過鍵盤獲取
    struct student stu;
    // 數組不須要取地址,變量須要取地址
    scanf("%s%d%d%s", stu.name, &stu.age, &stu.score,stu.addr);

    printf("姓名:%s\n", stu.name);
    printf("年齡:%d\n", stu.age);
    printf("成績:%d\n", stu.score);
    printf("地址:%s\n", stu.addr);

    return 0;
}
結構體 使用案例:鍵盤獲取
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

struct student
{
    // 結構體成員須要偏移對齊
    char name[21];
    int age;
    char sex;
    int score[3];
    char addr[51];
};

int main(void)
{
    // 結構體數組
    struct student stu[]=
    {
        {"蠻王",34,'M',88,99,0,"諾克薩斯"},
        {43,'M',0,0,0,"德瑪西亞",.name = "蓋倫" },
        {"拉克絲",18,'F',2,2,2,"窯子"}
    };

    // 打印
    for (int i = 0; i < 3; i++)
    {
        printf("姓名:%s\n", stu[i].name);
        printf("年齡:%d\n", stu[i].age);
        printf("性別:%s\n", stu[i].sex == 'M' ? "" : "");
        printf("成績:%d\n", stu[i].score[0]);
        printf("成績:%d\n", stu[i].score[1]);
        printf("成績:%d\n", stu[i].score[2]);
        printf("地址:%s\n\n", stu[i].addr);
    }

    // 經過sizeof求出結構體
    printf("結構體數組大小:%d\n", sizeof(stu));
    printf("結構體數組元素大小:%d\n", sizeof(stu[0]));
    printf("結構體數組元素個數:%d\n", sizeof(stu[0])/sizeof(stu[0]));

    return 0;
}
結構體 使用案例:結構體數組
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

struct student
{
    char name[21];
    int age;
    char sex;
    int score[3];
    char addr[51];
};

int main(void)
{
    struct student stu[]=
    {
        {"蠻王",34,'M',88,99,0,"諾克薩斯"},
        {.age = 43,'M',0,0,0,"德瑪西亞",.name = "蓋倫" },
        {"拉克絲",18,'F',2,2,2,"窯子"}
    };

    // 根據年齡排序
    for (int i = 0; i < 3 - 1; i++)
    {
        for (int j = 0; j < 3 - 1 - i; j++)
        {
            if (stu[j].age > stu[j + 1].age)
            {
                struct student temp = stu[j];
                stu[j] = stu[j + 1];
                stu[j + 1] = temp;
            }
        }
    }


    // 打印
    for (int i = 0; i < 3; i++)
    {
        printf("姓名:%s\n", stu[i].name);
        printf("年齡:%d\n", stu[i].age);
        printf("性別:%s\n", stu[i].sex == 'M' ? "" : "");
        printf("成績:%d\n", stu[i].score[0]);
        printf("成績:%d\n", stu[i].score[1]);
        printf("成績:%d\n", stu[i].score[2]);
        printf("地址:%s\n\n", stu[i].addr);
    }

    return 0;
}
結構體 使用案例:結構體排序
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

// 爲 struct student 起別名
typedef struct student ss;

struct student
{
    char name[21];
    int age;
    char sex;
    int score[3];
    char addr[51];
};

int main(void)
{

    // 輸出結構體大小
    // printf("%d\n", sizeof(struct student));

    // 建立結構體指針類型的堆空間並指定結構體內存大小
    ss * p = (ss *)malloc(sizeof(ss) * 3);
    prinf("結構體指針大小:%d", sizeof(ss*));

    // 經過鍵盤存儲內容
    for (int i = 0; i < 3; i++)
    {
        scanf("%s%d,%c%d%d%d%s", p[i].name, &p[i].age, &p[i].sex, &p[i].score[0], &p[i].score[1], &p[i].score[2], p[i].addr);
    }

    // 打印
    for (int i = 0; i < 3; i++)
    {
        printf("姓名:%s\n", p[i].name);
        printf("年齡:%d\n", p[i].age);
        printf("性別:%s\n", p[i].sex == 'M' ? "" : "");
        printf("成績:%d\n", p[i].score[0]);
        printf("成績:%d\n", p[i].score[1]);
        printf("成績:%d\n", p[i].score[2]);
        printf("地址:%s\n\n", p[i].addr);
    }

    // 釋放內存
    free(p);

    return 0;
}
結構體 使用案例:結構體堆空間使用
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

// 遊戲案例
/*
struct 技能
{
    名稱
    等級
    傷害
    範圍
    消耗
    冷卻
}

struct 人物信息
{
    等級
    經驗
    金錢
    hp
    mp
    力量
    智力
    敏捷
    struct 技能 skills[4]
}

struct 人物信息 info;
info.skills[0].名稱

*/

struct scores
{
    int c1;//c語言
    int cpp;//c++
    int cs;//c#
};

struct student
{
    char name[21];
    int age;
    struct scores ss;
    char addr[51];
};

int main(void)
{
    // 賦值
    struct student stu = { "貂蟬",18,99,99,99,"徐州" };
    // 打印
    printf("%s\n%d\n%d\n%d\n%d%\n%s\n", stu.name, stu.age, stu.ss.c1, stu.ss.cpp, stu.ss.cs,stu.addr);

    // 賦值
    strcpy(stu.name, "小喬");
    stu.age = 16;
    stu.ss.c1 = 88;
    stu.ss.cpp = 88;
    stu.ss.cs = 88;
    strcpy(stu.addr, "江東");
    // 打印
    printf("%s\n%d\n%d\n%d\n%d%\n%s\n", stu.name, stu.age, stu.ss.c1, stu.ss.cpp, stu.ss.cs, stu.addr);

    printf("學生結構體大小%d\n",sizeof(stu));
    printf("學生結構體大小%d\n", sizeof(stu.ss));
    printf("名稱數組大小%d\n", sizeof(stu.name));


    return 0;
}
結構體 使用案例:結構體嵌套結構體
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

struct student
{
    char name[21];
    int age;
    int score;
    char addr[51];
};

int main(void)
{
    // 賦值
    struct student stu = {"孫嫩香",26,60,"巴蜀"};
    // 賦值變量
    struct student s1 = stu;
    
    // 深拷貝和淺拷貝
    strcpy(s1.name, "甘夫人");
    s1.age = 28;
    s1.score = 80;

    // 輸出
    printf("%s\n", stu.name);
    printf("%d\n", stu.age);
    printf("%d\n", stu.score);

    
    return 0;
}
結構體 使用案例:結構體賦值
#include<stdio.h>
#include <string.h>
 
//結構體類型的定義
struct stu
{
       char name[50];
       int age;
};
 
//函數參數爲結構體普通變量
void set_stu(struct stu tmp)
{
       strcpy(tmp.name, "mike");
       tmp.age = 18;
       printf("tmp.name = %s, tmp.age = %d\n", tmp.name, tmp.age);
}
 
int main()
{
       struct stu s = { 0 };
       set_stu(s); //值傳遞
       printf("s.name = %s, s.age = %d\n", s.name, s.age);
 
       return 0;
}
結構體 使用案例:結構體普通變量作函數參數
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>


typedef struct student ss;
struct student
{
    // char name[21]
    char *name;
    int age;
    int score;
    char addr[51];
};

void fun(ss stu)
{
    strcpy(stu.name, "盧俊義");
}


int main(void)
{
    ss stu = { NULL,50,101,"水泊梁山" };
    stu.name = (char*)malloc(sizeof(char) * 21);
    strcpy(stu.name, "松江");
    printf("%s\n", stu.name);
    fun(stu);
    printf("%s\n", stu.name);

    return 0;
} 
結構體 使用案例:結構體普通變量作函數參數 2

結構體和指針

1、說明

經過指針結合結構體進行操做c#

2、案例

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

// 結構體稱爲爲指針類型
struct student
{
    char* name;
    int age;
    int *scores;
    char* addr;
};

int main(void)
{
    struct student stu;

    // 常量:stu.name = "張春生";//err
    // 開闢堆空間
    stu.name = (char*)malloc(sizeof(char) * 21);
    stu.scores = (int*)malloc(sizeof(int) * 3);
    stu.addr = (char*)malloc(sizeof(char) * 51);

    // 賦值
    strcpy(stu.name, "張三");
    stu.age = 18;
    stu.scores[0] = 88;
    stu.scores[1] = 99;
    stu.scores[2] = 100;
    strcpy(stu.addr, "北京市");

    // 打印
    printf("%s\n", stu.name);
    printf("%d\n", stu.age);
    printf("%d\n", stu.scores[0]);
    printf("%d\n", stu.scores[1]);
    printf("%d\n", stu.scores[2]);
    printf("%s\n", stu.addr);

    // 釋放內存
    free(stu.name);
    free(stu.scores);
    free(stu.addr);

    return 0;
}
結構體和指針 使用案例
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

// 結構體稱爲爲指針類型
struct student
{
    char name[21];
    int age;
    int scores[3];
    char addr[51];
};

int main(void)
{
    // 結構體指針
    struct student stu = {"林沖",30,100,100,100,"邊境"};

    // 賦值結構體指針
    struct student * p = &stu;

    // 打印值
    // printf("%s\n", (*p).name);
    // printf("%d\n", (*p).age);
    // 結構體指針->成員
    // 結構體變量.成員
    printf("%s\n", p->name);
    printf("%d\n", p->age);
    printf("%d\n", p->scores[0]);
    printf("%d\n", p->scores[1]);
    printf("%d\n", p->scores[2]);
    printf("%s\n", p->addr);

    return 0;
}
結構體和指針 使用案例:2
#include<stdio.h>
#include <string.h>
#include <stdlib.h>
 
//結構體類型的定義
struct stu
{
       char name[50];
       int age;
};
 
int main()
{
       struct stu *p = NULL;
 
       p = (struct stu *)malloc(sizeof(struct  stu));
 
       //若是是指針變量,經過->操做結構體成員
       strcpy(p->name, "test");
       p->age = 22;
 
       printf("p->name = %s, p->age=%d\n", p->name, p->age);
       printf("(*p).name = %s, (*p).age=%d\n", (*p).name,  (*p).age);
 
       free(p);
       p = NULL;
 
       return 0;
}
結構體和指針 使用案例:堆區結構體變量
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>


typedef struct student ss;
struct student
{
    char* name;
    int age;
    int* scores;
    char* addr;
};

int main(void)
{
    // 開闢 結構體堆空間
    ss* p = (ss*)malloc(sizeof(ss) * 3);

    // 開闢 結構體成員堆空間
    for (int i = 0; i < 3; i++)
    {
        (p + i)->name = (char*)malloc(sizeof(char*) * 21);
        (p + i)->scores = (int*)malloc(sizeof(int) * 3);
        (p + i)->addr = (char*)malloc(sizeof(char*) * 51);
    }

    // 賦值
    for (int i = 0; i < 3; i++)
    {
        scanf("%s%d%d%d%d%s", p[i].name, &p[i].age, &p[i].scores[0], &p[i].scores[1], &p[i].scores[2], &p[i].addr);
    }

    // 輸出
    for (int i = 0; i < 3; i++)
    {
        printf("%s\n", p[i].name);
        printf("%d\n", p[i].age);
        printf("%d\n", p[i].scores[0]);
        printf("%d\n", (p + i)->scores[1]);
        printf("%d\n", (p + i)->scores[2]);
        printf("%s\n", (p + i)->addr);
    }

    // 釋放堆空間內層
    for (int i = 0; i < 3; i++)
    {
        free(p[i].name);
        free(p[i].scores);
        free(p[i].addr);
    }

    // 釋放外層
    free(p);

    return 0;
}
結構體和指針 使用案例:結構體套一級指針
#include<stdio.h>
#include <string.h>
 
//結構體類型的定義
struct stu
{
       char name[50];
       int age;
};
 
//函數參數爲結構體指針變量
void set_stu_pro(struct stu *tmp)
{
       strcpy(tmp->name, "mike");
       tmp->age = 18;
}
 
int main()
{
       struct stu s = { 0 };
       set_stu_pro(&s); //地址傳遞
       printf("s.name = %s, s.age = %d\n", s.name, s.age);
 
       return 0;
}
結構體和指針 使用案例:結構體指針變量作函數參數
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>


typedef struct student ss;
struct student
{
    char name[21];
    //char *name;
    int age;
    int score;
    char addr[51];
};

void fun(ss * p)
{
    strcpy(p->name, "公孫勝");
}

int main(void)
{
    // 結構體指針做爲函數參數傳遞
    ss stu = { "吳用",50,101,"水泊梁山" };
    printf("%s\n", stu.name);
    fun(&stu);
    printf("%s\n", stu.name);
    return 0;
}
結構體和指針 使用案例:結構體指針變量作函數參數 2
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>


typedef struct student ss;
struct student
{
    char name[21];
    int age;
    int score[3];
    char addr[51];
};

// 數組做爲函數參數退化爲指針、丟失元素靜度、須要傳遞個數
void BubbleSort(ss * stu, int len)
{
    for (int i = 0; i < len - 1; i++)
    {
        for (int j = 0; j < len - i - 1; j++)
        {
            // if(stu[j].age>stu[j+1].age)
            if ((stu + j)->age > (stu + j + 1)->age)
            {
                ss temp = stu[j];
                stu[j] = stu[j + 1];
                stu[j + 1] = temp;
            }
        }
    }
}

int main(void)
{
    ss stu[3] = 
    { 
        { "魯智深",30,33,33,33,"五臺山" },
        { "呼延灼",45,33,33,33,"汴京" },
        { "顧大嫂",22,33,33,33,"汴京" },
    };

    // 傳遞結構體數組、 名稱、經過函數排序
    BubbleSort(stu, 3);

    // 輸出
    for (int i = 0; i < 3; i++)
    {
        printf("姓名:%s\n", stu[i].name);
        printf("年齡:%d\n", stu[i].age);
        printf("成績:%d\n", stu[i].score[0]);
        printf("成績:%d\n", (stu + i)->score[1]);
        printf("成績:%d\n", (stu + i)->score[2]);
        printf("地址:%s\n", (stu + i)->addr);
    }
    return 0;
}
結構體和指針 使用案例:結構體數組名作函數參數
//結構體類型的定義
struct stu
{
       char name[50];
       int age;
};
 
void fun1(struct stu * const p)
{
       //p = NULL; //err
       p->age = 10; //ok
}
 
//void fun2(struct stu const*  p)
void fun2(const struct stu *  p)
{
       p = NULL; //ok
       //p->age = 10; //err
}
 
void fun3(const struct stu * const p)
{
       //p = NULL; //err
       //p->age = 10; //err
}
結構體和指針 使用案例:const修飾結構體指針形參變量
相關文章
相關標籤/搜索