前言:
我們在前面的C語言學習過程中,學習了各種數據類型,例如:整型數據類型、字符型數據類型,浮點型數據類型等,這些數據類型的設計都是為了對實際生活中的各種數據進行在計算機上的儲存,但我們生活中還有一些數據無法使用以上單一的數據類型進行描述,例如;如何在計算機上保存一個人的信息,一個人的信息包括名字(字符)、年齡(整型),身高(浮點型)、體重(浮點型)等等。此時,C語言就設計出了結構體來對一些復雜的數據進行描述及數據的儲存。
結構體類型的聲明
結構的基礎知識
結構是一些值的集合,這些值稱為成員變量。結構的每個成員可以是不同類型的變量。
結構體的聲明
struct tag
{
member-list;
}variable-list;//注意這里的分號不要漏寫
舉個例子:
描述一個學生的信息。
struct Stu
{
char name[20];//名字
int age;//年齡
char sex[5];//性別
char id[10];//學號
}s1;//結構體成員變量
結構成員的類型
結構的成員可以是標量、數組、指針,甚至是其他結構體。
結構體變量的定義和初始化
有了結構體類型,那如何定義變量,其實很簡單。
結構體變量的定義有兩種:
- 在創(chuàng)建結構體的同時定義結構體變量。
- 在結構體的外邊定義結構體變量。
#include <stdio.h>
struct Point
{
int x;
int y;
}p1; //聲明類型的同時定義變量p1(第一種定義方式)
struct Point p2; //定義結構體變量p2(第二種定義方式)
struct Point p3 = { 1, 2 };//初始化:定義變量的同時賦初值。
struct Stu//類型聲明
{
char name[15];//名字
int age;//年齡
};
struct Stu s = { "zhangsan", 20 };//初始化
struct Node
{
int data;
struct Point p;//結構體嵌套
struct Node* next;
}n1 = { 10, {4,5}, NULL }; //結構體嵌套初始化
struct Node n2 = { 20, {5, 6}, NULL };//結構體嵌套初始化
結構體成員訪問
我在之前的C語言操作符詳解文章中詳細講解過結構體成員訪問操作符,這里就簡要介紹一下,不過多贅述了,有興趣的可以看下我之前的文章:
- 文章鏈接:C語言:操作符詳解
結構體成員訪問操作符分為點操作符(.) 和 箭頭操作符(->)。
結構體成員訪問操作符接受兩個操作數。
使用格式:
- .
結構體.成員名- ->
結構體指針->成員名
舉例:點操作符
#include <stdio.h>
struct stu
{
char name[15];
int age;
};
int main()
{
struct stu s1 = { "zhangsan", 20 };//定義及其初始化
printf("%s %d\n", s1.name, s1.age);
//通過點操作符(.)訪問到結構體變量s1中的name成員
//通過點操作符(.)訪問到結構體變量s1中的age成員
return 0;
}
注意:
如果你在結構體定義初始化的時候不按照結構體內部成員變量的順序來初始化的時候,就需要使用點操作符來指向對應的結構體成員。
#include <stdio.h>
struct stu
{
char name[15];
int age;
};
int main()
{
struct stu s1 = { "zhangsan", 20 };
struct stu s2 = { .age = 20, .name = "zhangsan" };
printf("%s %d\n", s1.name, s1.age);
printf("%s %d\n", s2.name, s2.age);
return 0;
}
舉例:箭頭操作符
#include <stdio.h>
struct stu
{
char name[15];
int age;
};
int main()
{
struct stu s1 = { "zhangsan", 20 };//定義及其初始化
struct stu* p1 = &s1;//結構體指針p1指向s1的地址
printf("%s %d\n", p1->name, p1->age);
//通過箭頭操作符(->)通過p1指針訪問到結構體變量s1中的name成員
//通過箭頭操作符(->)通過p1指針訪問到結構體變量s1中的age成員
return 0;
}
結構體傳參
當我們需要把結構體傳到某一個函數內部調用時,就涉及到結構體傳參的知識。
舉例:
設計一個print函數來打印結構體的內容。
函數調用時,函數傳參分為傳值調用和傳址調用。
如果你不太了解,這里放上我的另一篇文章,里面詳細介紹了有關函數的相關知識,有興趣的可以點擊閱讀:
- 文章鏈接:C語言:函數詳解
這里我們用兩種形式分別實現(xiàn)一下:
傳值調用:
#include <stdio.h>
struct stu
{
char name[15];
int age;
};
//結構體傳參
void print(struct stu s)
{
printf("%s %d\n", s.name, s.age);
}
int main()
{
struct stu s1 = { "zhangsan", 20 };//定義及其初始化
print(s1);//結構體傳值
return 0;
}
我們知道,函數傳參時使用傳值調用,形參是實參的一份臨時拷貝。
所以這里在結構體s1傳參的時候,其實是把s1的內容完全復制了一份讓print函數中的結構體s來接收,打印的是s中拷貝的s1的內容。
傳址調用:
#include <stdio.h>
struct stu
{
char name[15];
int age;
};
//結構體地址傳參
void print(struct stu* s)
{
printf("%s %d\n", s->name, s->age);
}
int main()
{
struct stu s1 = { "zhangsan", 20 };//定義及其初始化
print(&s1);//結構體傳址
return 0;
}
函數傳參時使用傳址調用,形參是實參的地址。
所以這里在結構體s1傳參的時候,其實是把s1的地址傳過去,print函數中的結構體指針s接受s1的地址,然后通過箭頭操作符,通過指針s找到s1的空間,最后打印的是s1的內容。
思考:
上面的兩種傳參函數哪個好些?
答案是:首選傳址調用的函數。
原因:
函數傳參的時候,參數是需要壓棧的。
如果傳遞一個結構體對象的時候,結構體過大,參數壓棧的的系統(tǒng)開銷比較大,所以會導致性能的下降。
結論:
結構體傳參的時候,盡量要傳結構體的地址。
本篇關于C語言結構體的講解就到此結束了,感興趣的的小伙伴點點贊,點點關注,謝謝大家的閱讀哦?。?!
但是對于結構體的知識還不止這些,關于結構體內存對齊、結構體實現(xiàn)位段、枚舉和聯(lián)合的講解會放在后邊繼續(xù)介紹,點點關注,后期不錯過哦。??文章來源:http://www.zghlxwxcb.cn/news/detail-789562.html
我相信大家在編寫代碼的時候常常會出現(xiàn)各種各樣的錯誤,但又不知道錯誤在哪,搞得自己痛苦不堪,本博主告訴你不用擔心,我下一篇將會對代碼的實用調試技巧出一篇文章,詳細介紹各種調試工具,幫助你更好的發(fā)現(xiàn)問題,解決問題哦。
你們的鼓勵就是我的動力,歡迎下次繼續(xù)閱讀?。?!??????文章來源地址http://www.zghlxwxcb.cn/news/detail-789562.html
到了這里,關于C語言:結構體詳解(簡單易懂)的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!