🌞 “少年有夢不至于心動,更要付諸行動。” 今天我們一起學習一下結構體的相關內容!
結構體
- 🎈1.結構體的聲明
- 1.1結構的基礎知識
- 1.2結構的聲明
- 1.3結構成員的類型
- 1.4結構體變量的定義和初始化
- 🎈2.結構體成員的訪問
- 2.1結構體變量訪問成員
- 2.2結構體指針訪問指向變量的成員
- 🎈3.結構體傳參
🎈1.結構體的聲明
1.1結構的基礎知識
📖結構是一些值的集合,這些值稱為成員變量,結構的每個成員可以是不同類型的變量。
1.2結構的聲明
📝為什么會出現結構體呢?在我們當前的一些學習中,我們學過的類型都是內置類型,例如:char short int double
等等。但是,它們無法描述一個復雜的對象,比方說人,我們很難用一個類型描述出它。相反,我們可能需要通過性別、年齡、身高、體重等等來進行描述。
🧩對于結構體的聲明,格式如下:
struct tag
{member-list;//成員變量的列表
}variable-list;//變量列表
📖下面,給出一個學生的結構體的聲明:
struct Stu//struct是結構體的關鍵字
{//學生的相關屬性char name[20];//姓名int age;//年齡char sex[5];//性別char tele[12];//電話
}s3,s4;
//s3,s4是結構體類型的變量,但是s3,s4是全局變量。
int main()
{struct Stu s1;struct Stu s2;//s1,s2也是結構體類型的變量,但是是局部變量return 0;
}
🔎這里的話,可能有的同學在想,如果每次在主函數內來定義一個結構體變量都要加struct Stu
是不是太麻煩了,能不能把這個去掉呢,或者說有沒有更簡單的表達方法呢?我們這個時候,就需要用到typedef
(typedef顧名思義是類型定義的,這里理解為類型重命名。鏈接: 關于關鍵字講解的鏈接)那么,程序可以做以下修改:
typedef struct Stu//struct是結構體的關鍵字
{//學生的相關屬性char name[20];//姓名int age;//年齡char sex[5];//性別char tele[12];//電話
}Stu;//Stu是重命名產生的新的類型
int main()
{Stu s1;Stu s2;//s1,s2是結構體類型的變量return 0;
}
1.3結構成員的類型
📖結構體成員的類型可以是標量、數組、指針,甚至是其他結構體。
struct B
{int a;short b;
};
struct C
{char c;int num;int arr[10];double* p;struct B b;struct B* p;
};
1.4結構體變量的定義和初始化
🧩結構體變量的定義:
struct A
{int age;char sex;
}a1;//a1是全局變量
struct A a2;//a2也是全局變量
int main()
{struct A a3;//局部變量return 0;
}
📖當我們想要給這些變量一些值的時候,我們就需要對變量進行初始化:
struct A
{int age;char sex;int arr[10];
}a1;//a1是全局變量
struct A a2;//a2也是全局變量
int main()
{//對于結構體的初始化可以用一對大括號來進行//按照順序初始化struct A a3 = { 18,'M',{1,2,3,4,5,6,7,8,9,10} };//局部變量//給指定的成員初始化struct A a4 = { .age = 20,.arr = {6,6,6} };return 0;
}
🔎我們可以通過監視來看看變量初始化的情況:
🎈2.結構體成員的訪問
2.1結構體變量訪問成員
📖結構變量的成員通過點操作符
(.)
訪問的,點操作符要接受兩個操作數。
下面我們給出示例,帶大家了解一下:
#include <stdio.h>
#include <string.h>
struct A
{char name[20];int age;char sex;
};
void Set_a(struct A t)
{t.age = 10;//t.name = "zhangsan";//這里我們發現會報錯,因為name是數組名,數組是常量的地址,不能改變,這里我們就需要用到strcpy函數來進行拷貝strcpy(t.name, "zhangsan");//字符串拷貝t.sex = 'M';
}
int main()
{struct A a = { 0 };//寫一個函數給a中存放數據Set_a(a);return 0;
}
🔎我們上面這段代碼對不對呢?變量a是否被初始化了呢?這里,我們調試著看一看:
🧩我們發現a并沒有被初始化,這是為什么呢?
?注意:實參傳遞給形參的時候,形參是實參的一份臨時拷貝,對形參的修改不會影響實參?
🎈通過前面的學習,我們知道這里應該通過傳地址的方式來改變實參的值:
#include <stdio.h>
#include <string.h>///strcpy函數的頭文件
struct A
{char name[20];int age;char sex;
};
void Set_a(struct A *t)
{(*t).age = 10;//t.name = "zhangsan";//這里我們發現會報錯,因為name是數組名,數組是常量的地址,不能改變,這里我們就需要用到strcpy函數來進行拷貝strcpy((*t).name, "zhangsan");//字符串拷貝(*t).sex = 'M';
}
int main()
{struct A a = { 0 };//寫一個函數給a中存放數據Set_a(&a);return 0;
}
🌞同樣的,既然這里我們用到了指針,不妨可以用指針訪問指向變量的成員!
2.2結構體指針訪問指向變量的成員
📖通過結構體指針來訪問成員可以通過操作符
->
來實現。
🧩上述代碼可以做以下修改,結果相同:
#include <stdio.h>
#include <string.h>
struct A
{char name[20];int age;char sex;
};
void Set_a(struct A* t)
{t->age = 10;strcpy(t->name, "zhangsan");//字符串拷貝t->sex = 'M';
}
int main()
{struct A a = { 0 };//寫一個函數給a中存放數據Set_a(&a);return 0;
}
🎈3.結構體傳參
#include <stdio.h>
struct B
{int date[100];int num;
};
struct B b = { {1,2,3},12 };
void Print1(struct B b)
{printf("%d\n", b.num);
}
void Print2(struct B *b)
{printf("%d\n", b->num);
}
int main()
{Print1(b);Print2(&b);return 0;
}
🔎對于上面兩個函數
Print1和Print2
,用哪個更好呢?這里我們選擇函數Print2
!
?注:函數傳參的時候,參數是需要壓棧的?如果傳遞一個結構體對象的時候,結構體過大,參數壓棧的系統開銷比較大,所以會導致性能的下降!
??結論:結構體傳參的時候,要傳結構體的地址!
好啦,關于結構體的知識點到這里就結束啦,后期會繼續更新C語言的相關知識,歡迎大家持續關注、點贊和評論!??????