天天看點

2021-3-11 【C結構體 、位域、共用體,typedef】

每日三百行代碼 第六天

  1. C 結構體
  2. 位域
  3. C 共用體
  4. C typedef

C結構體

//C數組允許定義可存儲相同類型資料項的變量
//結構是C程式設計中另一種使用者自定義的可用的資料類型
//它允許你存儲不同類型的資料項。

//定義結構
struct name{    //name 結構體标簽 
	int i;      //标準的變量定義 
	float a;
	double c;
	char b;
	int m[10];
	....
}zname;
//結構變量,定義在結構的末尾,最後一個分号之前
//可以指定一個或多個結構變量 

           
struct name{
	int i;
	double a;
	char c;
}; 
struct name t1,t2[10],*t3; 

//結構體的成員可以包含其他結構體,也可以包含指向自己結構體類型的指針
//通常這種指針的應用是為了實作一些更進階的資料結構 如:連結清單和樹等。

//此結構體包含其他結構體
struct COMPLEX{
	char string[100];
	struct SIMPLE a;
}; 

//此結構體包含了指向自己類型的指針
struct NODE{
	char string[100];
	struct NODE *next_node;
}; 
           
//結構體變量的初始化 
struct books{
	char name[100];
	char author[100];
	int cost;
} book={"goodstudy","eternity","100"}; 
           
//為了通路結構成員,我們使用成員通路運算符(.)
#include <stdio.h>
#include <string.h>
 
struct Books
{
   char  title[50];
   char  author[50];
   char  subject[100];
   int   book_id;
};

int main(){
	struct Books book;
	strcpy(book.title,"goodstudy");
	strcpy(book.author,"eternity");
	strcpy(book.subject,"abc");
	book.book_id=123456;
	
	printf( "Book title : %s\n", book.title);
    printf( "Book author : %s\n", book.author);
    printf( "Book subject : %s\n", book.subject);
    printf( "Book book_id : %d\n", book.book_id);
    return 0;
} 
           
//指向結構的指針
 
//定義指向結構的指針,方式與定義指向其他類型變量的指針相似
struct Books *struct_pointer;

//在上述定義的指針變量中存儲結構變量的位址
//為了查找結構變量的位址,把&運算符放在結構名稱的前面
struct_pointer = &book;

//為了使用指向該資料結構的成員,使用->運算符
struct_pointer->title;

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

struct Books{
	char title[100];
	char author[100];
	char subject[100];
	int book_id;
	
};
 
void printBook(struct Books *book){
	printf("Book title: %s\n",book->title);
	printf("Book author: %s\n",book->author);
	printf("Book subject: %s\n",book->subject);
	printf("Book book_id: %d\n",book->book_id);
}

int main(){
	struct Books Book1;//聲明 
	
	strcpy(Book1.title,"goodstudy");
	strcpy(Book1.author,"eternity");
	strcpy(Book1.subject,"abc");
	Book1.book_id=123456;
	
	printBook(&Book1);
	//通過傳Book1的位址來輸出Book1的資訊 
	
	return 0; 
}
           

位域

有些資訊在存儲時,并不需要占用一個完整的位元組
而隻需要占幾個或一個二進制位
如在存放一個開關量時,隻有0和1兩種狀态,用一位二進位即可
為了節省存儲空間,并使處理簡便,C語言又提供了一種資料結構
稱為"位域"或"位段" 

所謂"位域"是把一個位元組中的二進位劃分為幾個不同的區域
并說明每個區域的位數
每個域有一個域名,允許在程式中按域名進行操作
這樣就可以把幾個不同的對象用一個位元組的二進制位域來表示

典例:
//用1位二進位存放一個開關量時,隻有0和1兩種狀态
//讀取外部檔案格式--可以讀取非标準的檔案格式

//位域的定義和位域變量的說明
struct bs{
	int a:8;//a占8位 
	int b:2;//b占2位 
	int c:6;//c占6位 
}data; 

//一個位域存儲在同一個位元組中,如一個位元組所剩空間不夠存放另一個位域時
//則會從下一單元起開始存放該位域
//也可以有意使某位域從下一單元開始
struct bs{
	unsigned a:4;
	unsigned  :4;//空域 //int後四位填0表示不使用 
	unsigned b:4;//從下一個單元開始存放,占4位 
}; 
 
//由于位域不允許跨兩個位元組,是以位域的長度不能大于一個位元組的長度
//也就是說不能超過8位的二進位
//如果最大長度大于計算機的整數字長
//一些編譯器可能會允許域的記憶體重疊
//另一些編譯器可能會把大大于一個域的部分存儲在下一位元組中

//位域可以是無名位域,這時它隻用來作填充或調整位置
//無名的位域是不能使用的

#include<stdio.h>

int main(){
	struct bs{
		unsigned a:1;
		unsigned b:3;
		unsigned c:4;
	}bit,*pbit;
	bit.a=1;
	bit.b=7;
	bit.c=15;
	printf("%d %d %d\n",bit.a,bit.b,bit.c);
	pbit=&bit;//把位域變量bit的位址送給指針變量*pbit
	pbit->a=0;//用指針的方式給位域a重新指派
	pbit->b&=3;
	//使用了複合的位運算符"&=",相當于:pbit->b=pbit->b&3
	//位域b中原有值為7,與3作按位與運算的結果為3
	//111&011=011,十進制值為3
	pbit->c|=1;
	//使用了複合的位運算符"|=",相當于:pbit->c=pbit->c|1
	//1111|0001=1111,十進制值為15
	printf("%d %d %d\n",pbit->a,pbit->b,pbit->c);
	return 0; 
} 
           

C 共用體

//共用體是一種特殊的資料類型,允許你在相同的記憶體位置存儲不同的資料類型
//你可以定義一個帶有多成員的共用體
//但是任何時候隻能有一個成員帶有值
//共用體提供了一種使用相同的記憶體位置的有效方法

//定義共用體

union  Book{
	int i;
	float f;
	char str[100]; 
}data;
//表示一個變量(相同的記憶體位置)可以存儲多個多種類型的資料
//可以根據需要在一個共用體内使用任何内置的或者使用者自定義的資料類型
//共用體占用的記憶體應足夠存儲共用體中最大的成員 
//如:
#include<stdio.h>
#include<string.h>

union Data{
	int i;
	float f;
	char str[100];
}; 

int main(){
	union Data data;
	printf("Memory size occupied by data: %d\n",sizeof(data));
	return 0;
}
           
//通路共同體成員
//使用成員通路運算符(.)

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

union Data{
	int i;
	float f;
	char str[100];
}; 

int main(){
	union Data data;
	data.i=10;
	data.f=100.25;
	strcpy(data.str,"eternity");
	
	printf("%d %f %s\n",data.i,data.f,data.str);
	return 0;
}
//i和f的值有損壞,因為最後賦給變量的值占用了記憶體位置
//str能完好輸出

           
#include <stdio.h>
#include <string.h>
 
union Data
{
   int i;
   float f;
   char  str[20];
};
 
int main( )
{
   union Data data;        
 
   data.i = 10;
   printf( "data.i : %d\n", data.i);
   
   data.f = 100.25;
   printf( "data.f : %f\n", data.f);
   
   strcpy( data.str, "eternity");
   printf( "data.str : %s\n", data.str);
 
   return 0;
}
//所有成員都能完好輸出,因為同一時間隻用到一個成員
 
           

C typedef

//可以使用typedef來為一個類型取一個新名字
typedef unsigned char ASD;
ASD b1,b2;
//ASD為unsigned char 的縮寫

//可以對結構體使用typedef來定義一個新的資料類型名字
//然後使用這個新的資料類型來直接定義結構變量 
#include <stdio.h>
#include <string.h>
 
typedef struct Books
{
   char  title[50];
   char  author[50];
   char  subject[100];
   int   book_id;
}Book;

int main(){
	Book book;
	strcpy(book.title,"goodstudy");
	strcpy(book.author,"eternity");
	strcpy(book.subject,"abc");
	book.book_id=123456;
	
	printf( "Book title : %s\n", book.title);
    printf( "Book author : %s\n", book.author);
    printf( "Book subject : %s\n", book.subject);
    printf( "Book book_id : %d\n", book.book_id);
    return 0;
} 
           
//#define 是C指令,用于為各種資料類型定義别名

//typedef 僅限于為類型定義符号名稱
//#define 不僅可以為類型定義别名,也能為數值定義别名
 
//typedef是由編譯器執行解釋的,#define語句是由預編譯器進行處理的

//#define的簡單用法
#include<stdio.h>

#define TRUE 1
#define FALSE 0

int main(){
	printf("%d %d\n",TRUE,FALSE);
	return 0;
} 

           

繼續閱讀