C語言——結構體 (C語言入門結束~ 以後更新進階C )

@[toc]數組

1.結構體類型的聲明

結構體的基礎知識:markdown

結構體是一些值的集合,這些值稱爲成員變量。
結構體的每一個成員能夠是不一樣類型的變量。ide

結構體的由來 / 意義 / 做用:函數

現實生活中,咱們會遇到不少複雜的對象,這些複雜的對象僅經過c語言中的整型數據類型或者浮點數數據類型是沒法全面且準確的描述的,這時候咱們就須要用結構體來描述這些複雜的對象性能

結構體的聲明:學習

struct tag  //struct---結構體關鍵字  tag---結構體標籤   struct tag---結構體類型
{
    member - list;   //結構體成員列表
}variable - list;    //結構體變量列表

例如描述一個學生:3d

#include<stdio.h>

//描述一個學生---一些數據
//名字、年齡、電話、性別
//struct---結構體關鍵字  Stu---結構體標籤  struct Stu---結構體類型

struct Stu
{
    //成員變量
    char name[20];
    short age;
    char tele[12];
    char sex[5];
}s1, s2, s3;//s1,s2,s3 是三個全局的結構體變量,可是通常不推薦使用全局變量
            //由於全局變量能夠隨意更改,不便於控制管理
int main()
{
    struct Stu s; //建立結構體變量.臨時變量
    return 0;
}

結構體類型至關於 int 自己不佔據空間,只有當用結構體類型建立結構體變量的時候(利用int建立整型變量)才佔據內存空間。指針

舉例 中結構體類型是 struct Stu,若是咱們嫌棄這個名字太長了,能夠對其進行一個類型重定義,使用類型重定義關鍵字 typedef 將struct Stu 重定義成 Stu;重定義類型名稱後,結構體變量的建立僅需使用Stu,如圖:code

image-20210807135915584

結構體成員的類型: 結構體成員能夠是變量、數組、指針、甚至是其它結構體。對象


2.結構體變量的定義和初始化

①建立結構體類型的同時定義結構體變量

struct Point
{
    int x;
    int y;
}p1;//聲明類型的同時定義變量p1

②先建立結構體類型,再定義結構體變量

struct Point p2;  //先建立結構體類型,再定義結構體變量

③初始化:定義變量的同時賦初值

// 初始化例如:
 struct Point p3 = { 1,1 };
 Stu s = { " 潘 ",20,"11011912011","男" };

結構體裏包含結構體初始化:

#include<stdio.h>
struct S
{
    int a;
    char c;
    char arr[20];
    double d;
};

struct T
{
    char ch[10];
    struct S s;
    char* pc;
};

int main()
{
    int arr[]={1,2,3,4,5,6,7,8,9}
    //建立一個struct T 類型的結構體變量
    //初始化的時候,成員若是是結構體,須要用{ }括起來。

    struct T t = { "hello",{100, 'w' ,"hello world",3.14}, arr };
    //指針不知道賦什麼值的時候,能夠賦NULL
    //先用t.s 找到結構體類型成員 再用 .去訪問結構體成員裏面的成員 t.s.arr

    printf("%s\n", t.ch);     //打印 hello
    printf("%s\n", t.s.arr);  //打印 hello world
    printf("%lf\n",t.s.d);    //打印 3.14
    printf("%p\n", t.pc);     //打印 arr[]指針
    printf("%d\n", t.pc);     //打印 arr的值

    return 0;
}

3.結構體成員的訪問

結構體變量訪問成員結構變量的成員是經過點操做符( . )訪問的。點操做符接收兩個操做數。

image-20210807141819250

②結構體指針訪問指向變量的成員有時候咱們獲得的不是一個結構體變量,而是指向一個結構體的指針。

image-20210807141923733

再例如:

struct Stu
{
char name[20];
int age;
};

void print(struct Stu* ps)
{
printf("name = %s   age = %d\n", (*ps).name, (*ps).age);    //使用結構體指針訪問指向對象的成員
printf("name = %s   age = %d\n", ps->name, ps->age);
}

int main()
{
   struct Stu s = {"zhangsan", 20};
   print(&s);//結構體地址傳參
   return 0;
}

4.結構體傳參

#include<stdio.h>

typedef struct Stu
{
    //成員變量
    char name[20];
    short age;
    char tele[12];
    char sex[5];
}Stu;

void Print1(Stu s)
{
    printf("name:  %s\n", s.name);
    printf("age:   %d\n", s.age);
    printf("tele:  %s\n", s.tele);
    printf("sex:   %s\n", s.sex);
}

void Print2(Stu* ps)
{
    printf("name:  %s\n", ps->name);
    printf("age:   %d\n", ps->age);
    printf("tele:  %s\n", ps->tele);
    printf("sex:   %s\n", ps->sex);
}

int main()
{
    //struct Stu s;//建立結構體變量,局部結構體變量
    Stu s = { "張同窗",20,"11011912011","保密" };
    Print1(s);
    Print2(&s);
    return 0;
}

image-20210807142806823


上面的 print1 和 print2 函數哪一個好些?

答案是:首選 print2 函數。

image-20210807143710865

緣由:函數傳參的時候,參數是須要壓棧的。 若是傳遞一個結構體對象的時候,結構體過大,參數壓棧的的系統開銷比較大,因此會致使性能的降低。

結論:結構體傳參的時候,要傳結構體的地址。


拓展:

這裏咱們說到了一個概念:壓棧

以前的學習知道了,程序內存主要分爲三個區域,棧區、堆區、靜態區

棧區:局部變量、函數的形式參數、函數調用也開闢空間
堆區:動態內存分配、malloc / free、realloc、calloc
靜態區:全局變量、靜態變量

畫圖理解:

無標題

棧:

①插入一個元素-- - 壓棧
② 刪除一個元素-- - 出棧

棧的特色:先進後出,後進先出。

image-20210807145126088

相關文章
相關標籤/搜索