C語言入門-結構類型
- 2019 年 10 月 18 日
- 筆記
一、聲明結構類型
#include <stdio.h> int main(int argc, char const *argv[]) { // 聲明結構類型 struct date { int month; int day; int year; }; // 使用自定義的類型 struct date today; today.month = 9; today.day = 30; today.year = 2019; printf("Today is date is %i-%i-%in", today.year , today.month, today.day); return 0; } 二、在函數內/外 ?
- 和本地變數一樣,在函數內部聲明的結構類型只能在函數內部使用
- 所以通常在函數外部聲明結果類型,這樣就可以被多個函數使用了
#include <stdio.h> struct date { int month; int day; int year; }; int main(int argc, char const *argv[]) { struct date today; today.month = 9; today.day = 30; today.year = 2019; printf("Today is date is %i-%i-%in", today.year , today.month, today.day); return 0; } 三、聲明結構的形式
struct point{ int x; int y; } struct point p1,p2; // 其中p1和p2都是point // 裡面有x和y的值 還有另外一種形式:
struct{ int x; int y }p1 , p2 ; // p1和p2都是一種無名結構,裡面有x和y 當然了,還有一種更加常用的形式
struct point { int x; int y; }p1 , p2; p1和p2都是point,裡面有x和y的值
四、結構的初始化
struct date{ int month; int day; int year; }; int main(int argc, char const *argv[]) { struct date taday = {9 , 30 , 2019}; struct date thismonth = {.month=9 , .year=2019}; printf("Today is date is %i-%i-%in", taday.year,taday.month,taday.day ); printf("This month is %i-%i-%in", thismonth.year,thismonth.month,thismonth.day); return 0; } // Today is date is 2019-9-30 // This month is 2019-9-0 結構成員
- 結構和數組有點像
- 數組用[]運算符和下標訪問其成員 a[10] = 10;
- 結構用「 . " 運算符和名字訪問其成員 today.day , student.firstName
結構運算
- 要訪問整個結構,直接用結構變數的名字
- 對於整個結構,可以做賦值、取地址、也可以傳遞給函數參數
- p1 = (struct point) {5,10} ; 等於 p1.x = 5 , p1.y = 10;
- p1 = p2 ; 等於 p1.x = p2.x ; p1.y = p2.y;
結構指針
- 和數組不同,結構變數的名字並不是結構變數的地址,必須使用&運算符
- struct date *pDate = &today;
五、結構與函數
結構作為函數參數
int numberOfDays(struct date d); - 整個結構可以作為參數的值傳入函數
- 這時候是在函數內新建一個結構變數,並複製調用者的結構的值
- 也可以返回一個結構
- 這與數組完全不同
輸入結構
- 沒有直接的方式可以一次scanf一個結構
- 如果我們打算寫一個函數來讀入結果
#include <stdio.h> struct point { int x; int y; }; void getStruct(struct point p); void output(struct point p); int main() { struct point y = {0,0}; getStruct(y); output(y); return 0; } void getStruct(struct point p){ scanf("%d" , &p.x); scanf("%d" , &p.y); printf("%d , %dn", p.x , p.y); } void output(struct point p) { printf("%d , %dn", p.x , p.y); } // 2 // 3 // 2 , 3 // 0 , 0 - 但是讀入的結構如何送回來呢?
- 記住c語言函數在調用時是傳值的,所以函數中的p與main中的y是不同的
解決的方案
- 之前的方案,把一個結構傳入函數,然後在函數中操作,但是沒有返回回去
- 問題在於傳入函數的是外面那個結構體的克隆體,而不是指針
- 傳入結構和傳入數組是不同的
- 在這個輸入函數中,完全可以創建一個臨時的結構變數,然後把這個結構返回給調用者,但這並不常用,了解即可
#include <stdio.h> struct point { int x; int y; }; struct point getStruct(void); void output(struct point p); int main() { struct point y = {0,0}; y = getStruct(); output(y); return 0; } // 這裡返回一個struct struct point getStruct(void){ struct point p; scanf("%d" , &p.x); scanf("%d" , &p.y); printf("%d , %dn", p.x , p.y); return p; } void output(struct point p) { printf("%d , %dn", p.x , p.y); } // 5 6 // 5 , 6 // 5 , 6 - 最常用的就是結構指針作為參數
六、指向結構的指針
struct date { int month; int day; int year; }myday; struct date *p = &myday; (*p).month = 12; p->month = 12; 用->表示指針所指的結構變數中的成員
結構指針參數
struct point { int x; int y; }; struct point* getStruct(struct point *p); void output(struct point p); void print(const struct point *p); int main(int argc, char const *argv[]) { struct point y = {0,0}; getStruct(&y); output(y); output(*getStruct(&y)); print(getStruct(&y)); return 0; } struct point* getStruct(struct point *p) { scanf("%d" , &p->x); scanf("%d" , &p->y); printf("%d , %dn", p->x , p->y); return p; } void output(struct point p) { printf("%d , %dn", p.x , p.y); } void print(const struct point *p) { printf("%d , %dn", p->x , p->y); }

