Android NDK開發之旅5 C語言基礎 結構體

小楠總發表於2017-12-18

###結構體

####概念、定義於初始化方式

一種綜合的自定義的資料結構。

與Java中的類類似,可以有成員,包括變數和函式(函式指標)。

只有在宣告的時候才能用{}進行初始化,否則只能逐一賦值。

示例程式碼:

#include <stdio.h>
#include <stdlib.h>

struct Person{
	char* name;
	int age;
	void(*speek)();//函式指標,類似於Java中的成員方法
};

void speek(){
	printf("說話\n");
}

void main(){

	//結構體的初始化方式一
	struct Person p1 = {"小璐",20,speek};
	printf("我的名字是:%s,年齡:%d\n",p1.name,p1.age);

	p1.speek();
	
	//結構體的初始化方式二
	struct Person p2;
	p2.name = "小楠";
	p2.age = 20;
	p2.speek = speek;

	printf("我的名字是:%s,年齡:%d\n",p2.name,p2.age);
	p2.speek();

	system("pause");
}
複製程式碼

####結構體可以在定義之後跟著宣告或者初始化變數

struct Person{
	char* name;
	int age;
	void(*speek)();
}p1,p2={"小楠",14,speek};
複製程式碼

####匿名結構體

控制結構體變數的個數(限量版),相當於單例

struct{
	char* name;
	int age;
	void(*speek)();
}p1,p2={"小楠",14,speek};
複製程式碼

####結構體的巢狀,初始化的時候{}巢狀即可,或者連.操作

struct Teacher{
	char* name;
};

struct Student{
	struct Teacher t;
	char* name;
};
複製程式碼

####結構體與指標

struct Person* p = &p2;

printf("%s,%d",(*p).name,(*p).age);//等價於
printf("%s,%d",p->name,p->age);
複製程式碼

也就是說, -> 等價於 (*XXX).

####結構體陣列

struct Person persons[] = {{"小楠",20,speek},{"小璐",20,speek}};

//求出結構體陣列的大小
int size = sizeof(persons) / sizeof(struct Person);

//遍歷方式一,通過指標去遍歷
struct Person* p = persons;
for ( ; p < persons + size ; p++){
	printf("%s,%d\n",p->name,p->age);
}

//遍歷方式二,一般的陣列方式去遍歷
int i = 0;
for (; i < size ; i++){
	printf("%s,%d\n",persons[i].name,persons[i].age);
}
複製程式碼

####結構體的大小

位元組對齊,結構體變數的大小,必須是最寬基本資料型別的整數倍。通過空間換取時間來提升讀取效率。聯想:劉翔跨欄。

意義:提升讀取的效率。

struct Man{
	int age;//4位元組
	double weight;//8位元組
}m1 = {19, 20.0};

void main(){

	//大小應該是16
	printf("%d", sizeof(m1));

	system("pause");
}
複製程式碼

####結構體與動態記憶體分配

//動態分配10個Man結構體
struct Man* p = (struct Man*)malloc(sizeof(struct Man) * 10);

//初始化
int size = sizeof(p) / sizeof(struct Man);
struct Man* loop = p;
for (; loop<p+size ; loop++){
	loop->age = 20;
	loop->weight = 100.0;
}

//釋放記憶體
free(p);
複製程式碼

####typedef取別名,定義新的型別,方便使用

//typedef 型別取別名
//1.不同名稱代表在幹不同的事情typedef int jint;  
//2.不同情況下,使用不同的別名
//#if defined(__cplusplus)
//typedef _JNIEnv JNIEnv;
//typedef _JavaVM JavaVM;
//3.書寫簡潔
複製程式碼

整型取別名:

typedef int Age;
Age age = 10;
複製程式碼

Person結構體取別名:

typedef struct Person P;
P p;
複製程式碼

Person結構體指標取別名:

typedef struct Person* PP;
PP p = &p2;
複製程式碼

在結構體定義的時候取別名(對應以上兩種):

typedef struct Person{
	char* name;
	int age;
}P1,*P2;//P1是結構體的別名,P2是結構體指標的別名,與變數的宣告區分開(沒有typedef)
複製程式碼

使用的時候更加簡潔,更加像物件導向程式設計:

P1 p1;
P2 p2 = &p1;
複製程式碼

####終極例子:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <Windows.h>

//定義一個Girl結構體,包括屬性和方法
typedef struct Girl{
	char *name;
	int age;
	//函式指標
	void(*sayHi)(char*);
}Girl;//給結構體取一個別名Girl(別名可以與結構體原本的名字相同)

//Girl結構體指標取別名GirlP
typedef Girl* GirlP;

//結構體的成員函式
void sayHi(char* text){
	MessageBoxA(0, text, "title", 0);
}

//自定義的一個函式
void rename(GirlP gp1){
	gp1->name = "Lily";
}

void main(){
	Girl g1 = { "Lucy", 18, sayHi };
	GirlP gp1 = &g1;
	gp1->sayHi("Byebye!");
	//傳遞指標,改名(只有傳遞指標才能修改值,所以指標是比較常用的方式)
	rename(gp1);

	getchar();
}
複製程式碼

如果覺得我的文字對你有所幫助的話,歡迎關注我的公眾號:

公眾號:Android開發進階

我的群歡迎大家進來探討各種技術與非技術的話題,有興趣的朋友們加我私人微信huannan88,我拉你進群交(♂)流(♀)

相關文章