天天看點

C初階 - 07結構體.1.本章重點2.結構體的聲明3.結構體變量的定義和初始化4.結構體成員的通路5.結構體傳參

我決定了要成為海賊王便要為此而戰,我必須變的更強。———路飛

階段1目标:

基本了解C語言文法,站在全局,避去晦澀難懂,鮮明梳理C語言基本概念,為算法競賽等計算機專業比賽鋪好道路。傳統功夫講究點到為止,此階段僅點明文法知識,後續階段再進一步精進學習。

C初階 - 07結構體.1.本章重點2.結構體的聲明3.結構體變量的定義和初始化4.結構體成員的通路5.結構體傳參

 目錄

1.本章重點

2.結構體的聲明

2.1結構的基礎知識

2.2結構體的聲明

2.3結構成員的類型

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

3.1結構體變量的定義

3.2結構體變量的初始化

4.結構體成員的通路

5.結構體傳參

1.本章重點

結構體類型的聲明

結構體初始化

結構體成員通路

結構體傳參

2.結構體的聲明

2.1結構的基礎知識

結構是一些值的集合,這些值稱為成員變量。結構的每個成員可以是不同類型的變量。

比如說:人,或者書📕是一個複雜對象,屬性不止一個,是以就構成了成員變量。

//定義一本書
struct Book
{
	char name[20];
	char autor[20];
	float price;
};

//定義一個坐标
struct Point
{
	int x;
	int y;
};
           

注意:

這些都是結構體類型,并沒有建立變量,是以沒有占用空間。

2.2結構體的聲明

struct tag      //struct 名字     
{
	member - list;//成員變量清單
}variable - list;//結構體類型建立的變量
           

注意:(  struct不可省略,名字允許省略  )

  • struct關鍵字不能省略。因為struct是結構體類型關鍵字。
  • 結構體類型名是自定義的合法辨別符,說明該結構體類型獨有的名字。當結構體類型名預設時,為無名結構體。是以說明結構體類型名可以預設,但是關鍵字struct不可以。

我們看着貌似和剛剛我們建立的書📕和坐标這種結構體定義有所不同,即:在最後的分号之前多了個東西,那是什麼意思呢?

我們來對比思考一下,其實啊,這兩種寫法本質上是一樣的,隻不過一個是全局變量,一個是局部變量。

//定義一本書
struct Book
{
	char name[20];
	char autor[20];
	float price;
};

int main()
{
	struct Book b1;//結構體類型struct Book建立的局部變量b1
	struct Book b2;//結構體類型struct Book建立的局部變量b2
}
           
//定義一本書
struct Book
{
	char name[20];
	char autor[20];
	float price;
}b1, b2; //結構體類型struct Book建立的全局變量

int main()
{
	
}
           

兩種寫法都可以,不過是一個局部變量一個全局變量,一個放在記憶體的棧區一個放在記憶體的靜态區罷了。

比如說我們用結構體定義聲明一個學生,我們可以這樣寫:

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

int main()
{
	struct Stu a;//定義一個學生a

	return 0;
}
           

我們有時候在main()函數中嫌struct Stu結構體類型來定義變量,過于備援,一般會用重命名的方式再來把struct Stu這個結構體類型重新命名一下,比如:

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

int main()
{
	Stu a;
	return 0;
}
           

注意:

此處新定義的Stu不是變量哈,和剛剛的全局變量不一樣喲~,此處新定義的Stu仍然是結構體類型struct Stu,隻不過我們覺得備援換了種寫法,用typedef來重命名一下罷了~~

2.3結構成員的類型

結構的成員可以是标量、數組、指針,甚至是其他結構體。

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

有了結構體類型,那如何定義結構體變量?其實很簡單。

3.1結構體變量的定義

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

3.2結構體變量的初始化

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

//初始化:定義變量的同時賦初值。
struct Point p3 = { x, y };
           

注意:結構體變量初始化,賦的初值是與結構體中的類型順序相對應,且類型對應的。

那如果我們結構體中又嵌套一個結構體呢?改如何賦予初值??

struct S
{
	int a;
	char c;
	double d;
};

struct T
{
	struct S s;
	char name[20];
	int num;
};

int main()
{
	struct T t = { {2,'100',3.14},"張三",6 };
	return 0;
}
           

4.結構體成員的通路

結構變量的成員是通過點操作符(.)通路的。   點操作符接受兩個操作數。

struct S
{
	int a;
	char c;
	double d;
};

struct T
{
	struct S s;
	char name[20];
	int num;
};

int main()
{
	struct T t = { {2,'m',3.14},"張三",666 };
	printf("%d % c %f %s %d", t.s.a, t.s.c, t.s.d, t.name, t.num);
	return 0;
}
           

注意:

t的成員變量中含有struct S s這個結構體,中間仍然需要(.)先來通路t中的s,然後再用(.)來通路s中的成員變量。

在我的部落格 05操作符和表達式 這一章節中,我們知道用位址同樣可以通路成員變量,我們再來看一下叭~:

struct S
{
	int a;
	char c;
	double d;
};

struct T
{
	struct S s;
	char name[20];
	int num;
};

int main()
{
	struct T t = { {2,'m',3.14},"張三",666 };
	printf("%d % c %f %s %d\n", t.s.a, t.s.c, t.s.d, t.name, t.num);

	struct T* pt = &t;
	printf("%d % c %f %s %d\n", pt->s.a, pt->s.c, pt->s.d, pt->name, pt->num);
	return 0;
}
           

在結構體通路成員變量中,我們需要注意:

  • 如果我們是想通過位址來通路結構體中的成員,需要  ->
  • 如果我們是想通過變量來通路結構體中的成員,需要   .

5.結構體傳參

struct S
{
	int a[100];
	int num;
	char ch;
    double d;
};
void Print1(struct S ss)
{
	printf("%d %d %d %d %d %c %lf", ss.a[0], ss.a[1], ss.a[2], ss.a[3], ss.num, ss.ch, ss.d);
}
int main()
{
	struct S s = { {1,2,3,4,5,6},100,'w',3.14 };
	Print1(s);
	return 0;
}
           
C初階 - 07結構體.1.本章重點2.結構體的聲明3.結構體變量的定義和初始化4.結構體成員的通路5.結構體傳參

 我們看到,傳參的時候,此時是值傳遞,即:将我們的結構體變量s,原封不動的copy一份,來實作列印,其實是非常浪費空間的。那麼我們可以用位址來傳遞。

struct S
{
	int a[100];
	int num;
	char ch;
    double d;
};
void Print2(struct S* ss)
{
	printf("%d %d %d %d %d %c %lf", ss->a[0], ss->a[1], ss->a[2], ss->a[3], ss->num, ss->ch, ss->d);
}
int main()
{
	struct S s = { {1,2,3,4,5,6},100,'w',3.14 };
	Print2(&s);
	return 0;
}
           

上面的 Print1 和 Print2 函數哪個好些?

答案是:首選Print2函數

函數傳參的時候,參數是需要壓棧的。 如果傳遞一個結構體對象的時候,結構體過大,參數壓棧的的系統開銷比較大,是以會導緻性能的下降。

舉個好了解的栗子:

int Add(int x, int y)
{
	int z = x + y;
	return z;
}
int main()
{
	int a = 10; 
	int b = 20;
	int c = 0;
	c = Add(a, b);
	printf("%d", c);
	return 0;
}
           
C初階 - 07結構體.1.本章重點2.結構體的聲明3.結構體變量的定義和初始化4.結構體成員的通路5.結構體傳參

 總結:

結構體傳參的時候,要傳結構體的位址。