1. 程式人生 > >C語言再學習 -- 關鍵字struct(轉)

C語言再學習 -- 關鍵字struct(轉)

結構體的一般定義形式為:

標籤(tag)欄位允許為成員列表提供一個名字,這樣它就可以在後續的宣告中使用。標籤允許多個宣告使用同一個成員列表,並且建立同一種類型的結構。

struct 標籤{

型別名1 成員名1;

型別名2 成員名2;

……

型別名n 成員名n;   

}結構體變數;

1、如果 標籤 存在,結構體變數 不存在,定義如下:

struct Student{

char name[20];//姓名

int age;//年齡

float height;//身高

};


struct Student stu //Student 為標籤 stu 為結構體變數

2、如果 結構體變數 存在, 標籤 可有可無,定義如下:

struct Student{ //Student 可有可無

char name[20];//姓名

int age;//年齡

float height;//身高

}stu;

3、使用typedef起別名,標籤可有可無,結構體變數 位置變為該 型別名

typedef struct Student{ //Student 可有可無

char name[20];//姓名

int age;//年齡

float height;//身高

}Stu; //Stu 為型別名


Stu stu; //Stu 為型別名,stu 為結構體變數


4、注意,字串初始化不能直接賦值,需要使用 strcpy 函式

#include <stdio.h>

#include <string.h>


typedef struct

{

int n;

float m;

char name[20];

}Ptr;


int main (void)

{

Ptr p;

//Ptr p = {11, 12.9, "hello"};

strcpy (p.name, "hello"); //注意字串不能直接賦值

p.n = 11;

p.m = 12.9;

printf ("n = %d, name = %s, m = %g\n", p.n, p.name, p.m);

return 0;

}

輸出結果:

n = 11, name = hello, m = 12.9

一、結構體的定義

1、定義形式

 

結構體內部的元素,也就是組成成分,我們一般稱為"成員"。
結構體的一般定義形式為:​​​​​​​

struct 結構體名{

型別名1 成員名1;

型別名2 成員名2;

……

型別名n 成員名n;   

};

2、舉例

比如,我們定義一個學生​​​​​​​

struct Student{

char name[20];//姓名

int age;//年齡

float height;//身高

};

上面定義了一個叫做Student的結構體,共有name、age、height3個成員。呵呵,看到這裡是否有點面向物件的味道呢,其實這跟面向物件完全是兩碼事,只能說感覺有點像。

二、結構體變數的定義

前面只是定義了名字為Student的結構體型別,並非定義了一個結構體變數,就像int一樣,只是一種型別。
接下來定義一個結構體變數,方式有好多種。

1、先定義結構體型別,再定義變數

struct Student{

char name[20];//姓名

int age;//年齡

float height;//身高

};

struct Student stu;

定義了一個結構體變數,變數名為stu。struct和Student是連著使用的。

2、定義結構體型別的同時定義變數

struct Student{

char name[20];//姓名

int age;//年齡

float height;//身高

}stu;

結構體變數名為stu

3、直接定義結構體型別變數,省略型別名

struct {

char name[20];//姓名

int age;//年齡

float height;//身高

}stu;

結構體變數名為stu

三、結構體的注意點

1、不允許對結構體本身遞迴定義

如下做法是錯誤的,注意第3行

struct Student {

int age;

struct Student stu;

};

2、結構體內可以包含別的結構體​​​​​​​

struct Date {

int year;

int month;

int day;

};


struct Student {

char name[20];

struct Date birthday; //................(1)

};

注:(1)行

3、定義結構體型別,只是說明了該型別的組成情況,並沒有給它分配儲存空間,就像系統不為int型別本身分配空間一樣。只有當定義屬於結構體型別的變數時,系統才會分配儲存空間給該變數

struct Student {

char name[20];

int age;

};

//................在此之前,系統並沒有分配儲存空間
struct Student stu;//...............當執行到該6行時,系統才會分配儲存空間給stu變數。

4、結構體變數佔用的記憶體空間是其成員所佔記憶體之和,而且各成員在記憶體中按定義的順序依次排列

比如下面的Student結構體

struct Student {

char ch;

int num;

float height;

};

根據結構體記憶體對齊與補齊規則,這個Student變數共佔用記憶體:12位元組。

 

考慮一個問題, 空結構體所佔記憶體多大?

#include <stdio.h>


struct strudent

{


}stu;


int main (void)

{

printf ("sizeof (stu) = %d\n", sizeof (stu));

return 0;

}

輸出結果:

在C中, sizeof (stu) = 0

在C++中, sizeof (stu) = 1

四、結構體的初始化

將各成員的初值,按順序地放在一對大括號{}中,並用逗號分隔,一一對應賦值。
比如初始化Student結構體變數stu

struct Student {

char name[20];

int age;

};

struct Student stu = {"MJ", 27};

只能在定義變數的同時進行初始化賦值,初始化賦值和變數的定義不能分開,下面的做法是錯誤的:

struct Student stu;

stu = {"MJ", 27};

五、結構體的使用

1、一般對結構體變數的操作是以成員為單位進行的,引用的一般形式為:結構體變數名.成員名

struct Student {

char name[20];

int age;

};

struct Student stu;

stu.age = 27; // 訪問stu的age成員........(2)

(2)行對結構體的age成員進行了賦值。"."稱為成員運算子,它在所有運算子中優先順序最高

2、如果某個成員也是結構體變數,可以連續使用成員運算子"."訪問最低一級成員

struct Date {

int year;

int month;

int day;

};

struct Student {

char name[20];

struct Date birthday;

};

struct Student stu;

stu.birthday.year = 1986;

stu.birthday.month = 9;

stu.birthday.day = 10;

3、相同型別的結構體變數之間可以進行整體賦值

struct Student {

char name[20];

int age;

};

struct Student stu1 = {"MJ", 27};

struct Student stu2 = stu1; // 將stu1直接賦值給stu2

printf("age is %d", stu2.age);

輸出結果為: age is 27

六、結構體陣列

1、定義

跟結構體變數一樣,結構體陣列也有3種定義方式
(1)、

struct Student {

char name[20];

int age;

};

struct Student stu[5]; //定義1

(2)、

struct Student {

char name[20];

int age;

} stu[5]; //定義2

(3)、

struct {

char name[20];

int age;

} stu[5]; //定義3

上面3種方式,都是定義了一個變數名為stu的結構體陣列,陣列元素個數是5

2、初始化

struct {

char name[20];

int age;

} stu[2] = { {"MJ", 27}, {"JJ", 30} };

也可以用陣列下標訪問每一個結構體元素,跟普通陣列的用法是一樣的

七、結構體作為函式引數

將結構體變數作為函式引數進行傳遞時,其實傳遞的是全部成員的值,也就是將實參中成員的值一一賦值給對應的形參成員。因此,形參的改變不會影響到實參。

96E7DE2F-5EFE-4B92-A0A4-EE196E126A3D.png

  • 首先在(3)行定義了一個結構體型別Student
  • 在(4)行定義了一個結構體變數stu,並在(5)行將其作為實參傳入到test函式
    輸出結果為:

    24165811-5748e293af5f4dec8f1fb855727a3e76.png

    形參是改變了,但是實參一直沒有變過。

    八、指向結構體的指標變數

    1、每個結構體變數都有自己的儲存空間和地址,因此指標也可以指向結構體變數

    2、結構體指標變數的定義形式:struct 結構體名稱 *指標變數名

    3、 有了指向結構體的指標,那麼就有3種訪問結構體成員的方式

    (1)、結構體變數名.成員名
    (2)、(*指標變數名).成員名
    (3)、指標變數名->成員名

    38622765-4312-4EEE-8D42-148230B72355.png


    輸出結果為:

    24170725-fe1c21f2d61e4db1a3ea18223098c21b.png

轉載:https://blog.csdn.net/qq_29350001/article/details/53817234