天天看點

[C語言]菜鳥的一些了解-結構體,共用體,枚舉,位域結構體

結構體

時間真快!!假期就要過去了。這是我最難過的一個國慶,

感謝時間快,又不希望它過得這麼快。

前面學的數組,一旦定義了就隻能存儲定義的資料類型的資料了。

但是我們現實中每組資料不一定是由同一種資料類型組成。

比如:一個人的資訊是由  姓名 年齡 職業 等組成。

這就不可能用數組的存儲了。

C語言中提供了一種類型,結構體來解決這類問題,結構體可以将不同的資料類型封裝在一起。我們再對其進行引用。我們可以根據實際情況來構造不同的類型。

簡單的來了解:結構體就是我們自己定義的一個可以存儲不同資料類型的數組。

聲明結構體類型,其聲明如下:

要用到  struct 這個關鍵字

struct  結構體名

{

資料類型1 結構體成員1;

資料類型2 結構體成員2;

};注意:這個分号省略。

定義結構體變量。

聲明了結構體類型後,便可以使用該類型來定義結構體變量。

定義結構體變量有三種方式:

① 聲明結構體類型後,再定義結構體變量。

struct 結構體名

{

資料類型1 結構體成員1;

資料類型2 結構體成員2;

};

struct 結構體名 變量名1,變量名2;

注意:struct 不可省略。

②不聲明結構體類型,直接定義結構體變量。

struct 

{

資料類型1 結構體成員1;

資料類型2 結構體成員2;

}變量名1,變量名2;

③ 使用typedef 得到簡化的結構體類型名,再定義結構體變量

由于結構體資料類型的名字由辨別符合結構體名兩部分組成,書寫起來名字較長,是以,常常使用 typedef 來簡化。其用法如下:

typedef struct 結構體名

{

資料類型1 結構體成員1;

資料類型2 結構體成員2;

資料類型n 結構體成員n;

}stru;

就可以通過stru來定義結構體變量了。

stru s1,s2;

結構體變量的初始化和指派

代碼如下

struct s

{

char str[100];

int i;

};

struct s s1 = {“Hello”,8};

也可以單獨指派

strcpy(str,”Hello”);//這裡為什麼要這樣指派呢?我也沒有搞懂。

s1.i = 8;

通路結構體成員

通路結構體成員要用到成員操作符( . )就是一點。成員操作是二進制操作符,操作符前面的是結構體變量,後面是結果體成員。

例1.

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

typedef struct student
{
	char name[100];//姓名
	int age;//年齡
}Stu;
	
int main(void)
{

	Stu s1 = {"小明",22};
	Stu s2 = s1;//結構體變量之間可以互相輔助。當然要同一個結構體類型。
	Stu s3; 
	
	printf("s1.name = %s\n",s1.name);
	printf("s1.age = %d\n",s1.age);
	
	printf("s2.name = %s\n",s2.name);
	printf("s2.age = %d\n",s2.age);
	
	strcpy(s3.name,"小敏");
	s3.age = 20;
	
	printf("s3.name = %s\n",s3.name);
	printf("s3.age = %d\n",s3.age); 
	
	return 0;
}
           

結構體數組

定義結構體數組

其定義方式跟定義結構體變量一樣,有三種方式,隻不過定義數組要加[]

結構體數組的初始化和指派

例2

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

	typedef struct student
	{
		char name[100];//姓名
		int age;//年齡
		char gender;//性别
	}Stu;
	
int main(void)
{
	int i = 0;
	Stu st[4] = {{"raul",22,'M'},
		{"joe",23,'W'},
		{"philip",21,'M'},
		{"alan",20,'M'}
	};
	
	/*其數組容量可以大不可小。超過的容量沒有指派,編譯器會自動初始化為0
	  也可不寫,編譯器會根據元素的個數來決定。*/
 	printf("姓名\t年齡\t性别\n"); 
 	for(i = 0;i < 4; ++i)
 		printf("%s\t%d\t%c\n",st[i].name,st[i].age,st[i].gender);
 		
	return 0;
}
           

結果:

姓名    年齡    性别

raul     22      M

joe      23      W

philip   21      M

alan     20      M

指向堆空間的結構體指針

例3

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

typedef struct 
{
	char name[100];
	int age;
	char gender;
}Stu;

int main(void)
{
	Stu *p = NULL;
	p = (Stu *) malloc ( sizeof(Stu) );
	if(NULL == p)
	{
		printf("\n");
		exit(1);
	}
	
	printf("請輸入姓名:");
	gets(p->name);
	
	printf("請輸入年齡和性别:");
	scanf("%d %c",&p->age,&p->gender); 
	
	printf("姓名\t年齡\t性别\n");
	printf("%s\t%d\t%c\n",p->name,p->age,p->gender);
	return 0;
}
           

指向結構體數組元素的指針

例4

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

typedef struct 
{
	char name[200];
	int age;
	char gender;
}Stu;

int main(void)
{
	Stu st[4]={{"raul",22,'M'},
	{"joe",23,'W'},
	{"philip",21,'M'},
	{"alan",20,'M'}
	};
	Stu *p = st;
	
	for(p = st;p < st + 4;++p)
	{
		printf("%s\t",p->name);
		printf("%d\t",p->age);
		printf("%c\n",p->gender);
	}
	return 0;
}
           

注:指針變量名->成員名 編譯時内部自動轉化為 (*指針變量名).成員名。這是規定,沒有為什麼?

共用體

共用體(union)是C語言中的另一中進階資料結構,為什麼叫共用體,因為共用體的幾個不同類型的成員共享一塊記憶體空間。

共用體類型的定義

union 共用體名

{

資料類型 成員名;

資料類型1 成員名1;

..........................

};記住這裡分号跟結構體一樣不可省略。

定義共用體變量(有三種方式跟結構體一樣)

第一種

union data(也可以省略共用體名)

{

int a;

char c;

}ut,ut1;

第二種

union data

{

int a;

char c;

};

union data ut;

第三種

typedef union data

{

int a;

char c;

}t_un;

t_un ut;

使用t_un來定義共用體變量

共用體成員的指派

由于共用體實際上隻有一個有效成員,是以,無法想結構體那樣指派,共用體隻能為其賦一個值,如下

typedef union data

{

int a;

char c;

}t_un;

t_un tu = {1,’a’}//錯誤

t_un tu = {1};//正确

證明共用成員共享一塊記憶體空間

#include <stdio.h>

typedef union data
{
	int x;
	char c;
	float f;
}ty_u;

int main(void)
{
	ty_u ud;
	ud.x = 1;
	printf("x=%d c=%c f=%f\n",ud.x,ud.c,ud.f);
	
	ud.c = 'a';
	printf("x=%d c=%c f=%f\n",ud.x,ud.c,ud.f);
	
	ud.f = 8.1;
	printf("x=%d c=%c f=%f\n",ud.x,ud.c,ud.f);
	
	printf("輸出共用體成員的位址:\n");
	printf("x=%p\nc=%p\nf=%p\n",&ud.x,&ud.c,&ud.f); 
	return 0;
}	
           

輸入同一個記憶體空間。

枚舉

使用枚舉變量需要注意以下幾點:

① 枚舉成員值以此增加1

定義枚舉類型時,可以對枚舉成員顯示指派,其後的枚舉成員同樣在改值的基礎上加1,如下:

enum en

{A = 1, B,C,D = 8,E,F};

由于A指派為1 則後面是B = 2 C = 3  由于D指派為8 則E = 9,F = 10;

② 隻能使用整型數值初始化

如下指派是錯誤的

enum en

{A = 0.1,B,C,D,E,F};

建議整型以外的值,用const 定義  或define 

③ 不使用隻有一個枚舉成員的枚舉類型。

沒有必要這麼麻煩吧,直接使用const 

位域

位域屬于結構體,它允許在結構體内以位作為機關将其空間劃分為多個區域,并将其配置設定給結構體的各個成員。在程式中可以通過操作位域的各個成員來操作其中的區域。利用位域可以使用較少的位元組數來存儲資訊,其形式如下:

struct 結構體名

{

unsigned 位域成員名1:常量1;

unsigned 位域成員名2:常量2;

..................................................

資料類型 成員名;

........................

};

1.位域成員的類型隻能為int 和 unsigned 型

2.位域成員聲明中最後的常量值指定了該區域所占的位數,且該數組不能大于其資料類型所   

  占的位數。

3.位域成員和結構體成員可以交叉定義

4.位域成員通路方式與結構體成員通路方式完全一樣

繼續閱讀