欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語言結(jié)構(gòu)體(struct)的詳細(xì)講解

 更新時間:2022年03月31日 08:40:36   作者:DS小龍哥  
C語言中,結(jié)構(gòu)體類型屬于一種構(gòu)造類型(其他的構(gòu)造類型還有:數(shù)組類型,聯(lián)合類型),下面這篇文章主要給大家介紹了關(guān)于C語言結(jié)構(gòu)體(struct)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下

引言

當(dāng)前文章介紹動態(tài)堆空間內(nèi)存分配與釋放,C語言結(jié)構(gòu)體定義、初始化、賦值、結(jié)構(gòu)體數(shù)組、結(jié)構(gòu)體指針的相關(guān)知識點,最后通過一個學(xué)生管理系統(tǒng)綜合練習(xí)結(jié)構(gòu)體數(shù)組的使用。

1. 動態(tài)內(nèi)存管理

C語言代碼----->編譯----->鏈接------>可執(zhí)行的二進(jìn)制文件(windows下xxx.exe) 二進(jìn)制文件中的數(shù)據(jù)是如何擺放的? 文本數(shù)據(jù)段、靜態(tài)數(shù)據(jù)段、全局?jǐn)?shù)據(jù)段。

堆??臻g: 代碼在運行的時候才有的空間。 棧空間: 系統(tǒng)負(fù)責(zé)申請,負(fù)責(zé)釋放。比如: 函數(shù)形參變量、數(shù)組…… 堆空間: 程序員負(fù)責(zé)申請,負(fù)責(zé)釋放。

 #include <stdlib.h>     //標(biāo)準(zhǔn)庫頭文件
 void *malloc(int size); //內(nèi)存申請。 形參表示申請的空間大小,返回值:申請的空間的地址
 void free(void *p);     //內(nèi)存釋放。 形參就是要釋放的空間首地址。

動態(tài)空間申請示例。

 動態(tài)空間申請
 #include "stdio.h"
 #include "string.h"
 #include <stdlib.h>
 int main()
 {
     int *p=malloc(sizeof(int)); //申請空間
     if(p!=NULL)
     {
         printf("申請的空間地址: 0x%X\n",p);
         *p=888;
         printf("%d\n",*p);
     }
     free(p); //釋放空間
     return 0;
 }
 示例2:
 #include "stdio.h"
 #include "string.h"
 #include <stdlib.h>
 ?
 char *func(void)
 {
     char*str=malloc(100); //char str[100];
     if(str!=NULL)
     {
         strcpy(str,"1234567890");
         printf("子函數(shù)打印:%s\n",str);
         //free(str); //釋放空間
         return str;
     }
     else
     {
         return NULL;
     }
 }
 ?
 int main()
 {
     char *p=func();
     printf("主函數(shù)打印:%s\n",p);
     return 0;
 }

2. 結(jié)構(gòu)體

2.1 定義語法

結(jié)構(gòu)體的概念: 可存放不同數(shù)據(jù)類型的集合。 比如: 存放一個班級學(xué)生的信息。 可以使用一個結(jié)構(gòu)體存放一個學(xué)生的信息。 一個結(jié)構(gòu)體數(shù)組存放整個班級的學(xué)習(xí)信息。 數(shù)組的概念: 可存放相同數(shù)據(jù)類型的集合。

結(jié)構(gòu)體的定義語法:

 //聲明一種新類型-----數(shù)據(jù)類型
 struct <結(jié)構(gòu)體的名稱>
 {
     <結(jié)構(gòu)體的成員>1;
 <結(jié)構(gòu)體的成員>2;
 …………
 };  //最后有分號結(jié)束
 ?
 struct MyStruct 
 {
     char a;
     int b;
     float c;
     char str[100];
 };

2.2 定義示例

結(jié)構(gòu)體如何賦值? 如何訪問結(jié)構(gòu)體內(nèi)部成員

 #include "stdio.h"
 #include "string.h"
 #include <stdlib.h>
 ?
 //定義結(jié)構(gòu)體數(shù)據(jù)類型
 struct MyStruct
 {
     char a;
     int b;
     float c;
     char str[100];
 };
 int main()
 {
     struct MyStruct data={'A',123,456.789,"abcd"}; //data就是結(jié)構(gòu)體類型的變量
     //結(jié)構(gòu)體變量訪問內(nèi)部成員的語法:  . 點運算符
     printf("%c\n",data.a);
     printf("%d\n",data.b);
     printf("%f\n",data.c);
     printf("%s\n",data.str);
     return 0;
 }

2.3 初始化

 #include "stdio.h"
 #include "string.h"
 #include <stdlib.h>
 ?
 //定義結(jié)構(gòu)體數(shù)據(jù)類型
 struct MyStruct
 {
     char a;
     int b;
     float c;
     char str[100];
 }data={'A',123,456.789,"abcd"}; //data就是結(jié)構(gòu)體類型的變量
 ?
 int main()
 {
     //結(jié)構(gòu)體變量訪問內(nèi)部成員的語法:  . 點運算符
     printf("%c\n",data.a);
     printf("%d\n",data.b);
     printf("%f\n",data.c);
     printf("%s\n",data.str);
     return 0;
 }

2.4 結(jié)構(gòu)體賦值

   //結(jié)構(gòu)體變量訪問內(nèi)部成員的語法:  . 點運算符
 #include "stdio.h"
 #include "string.h"
 #include <stdlib.h>
 ?
 //定義結(jié)構(gòu)體數(shù)據(jù)類型
 struct MyStruct
 {
     char a;
     int b;
     float c;
     char str[100];
 }; 
 ?
 int main()
 {
     struct MyStruct data;//data就是結(jié)構(gòu)體類型的變量
     //成員單獨賦值
     data.a='A';
     data.b=123;
     data.c=456.789;
     strcpy(data.str,"abcd"); //數(shù)組賦值
 ?
     //結(jié)構(gòu)體變量訪問內(nèi)部成員的語法:  . 點運算符
     printf("%c\n",data.a);
     printf("%d\n",data.b);
     printf("%f\n",data.c);
     printf("%s\n",data.str);
     return 0;
 }

2.5 結(jié)構(gòu)體數(shù)組

 結(jié)構(gòu)體賦值分為兩種標(biāo)準(zhǔn):  C89 、C99
 ?結(jié)構(gòu)體數(shù)組
 #include "stdio.h"
 #include "string.h"
 #include <stdlib.h>
 ?
 //定義結(jié)構(gòu)體數(shù)據(jù)類型
 struct MyStruct
 {
     char a;
     int b;
     float c;
     char str[100];
 }; 
 ?
 int main()
 {
     struct MyStruct data[100];//data就是結(jié)構(gòu)體數(shù)組類型變量
     struct MyStruct data2[50];
 ?
     //成員單獨賦值
     data[0].a='A';
     data[0].b=123;
     data[0].c=456.789;
     strcpy(data[0].str,"abcd"); //數(shù)組賦值
 ?
     //結(jié)構(gòu)體變量訪問內(nèi)部成員的語法:  . 點運算符
     printf("%c\n",data[0].a);
     printf("%d\n",data[0].b);
     printf("%f\n",data[0].c);
     printf("%s\n",data[0].str);
     return 0;
 }

2.6 結(jié)構(gòu)體指針賦值

 #include "stdio.h"
 #include "string.h"
 #include <stdlib.h>
 //定義結(jié)構(gòu)體數(shù)據(jù)類型
 struct MyStruct
 {
     char a;
     int b;
     float c;
     char str[100];
 }; 
 ?
 int main()
 {
     //struct MyStruct buff[100];
     //struct MyStruct *data=buff; //結(jié)構(gòu)體指針類型變量
 ?
     struct MyStruct *data=malloc(sizeof(struct MyStruct));
     data->a='A';
     data->b=123;
     data->c=456.789;
     strcpy(data->str,"abcd");
 ?
     //結(jié)構(gòu)體指針訪問內(nèi)部成員的變量 通過  ->  運算符。 
     printf("%c\n",data->a);
     printf("%d\n",data->b);
     printf("%f\n",data->c);
     printf("%s\n",data->str);
     return 0;
 }

3. 學(xué)生管理系統(tǒng)

作業(yè): 學(xué)生管理系統(tǒng)

需求: (每一個功能都是使用函數(shù)進(jìn)行封裝) 1.實現(xiàn)從鍵盤上錄入學(xué)生信息。 (姓名、性別、學(xué)號、成績、電話號碼) 2.將結(jié)構(gòu)體里的學(xué)生信息全部打印出來。 3.實現(xiàn)根據(jù)學(xué)生的姓名或者學(xué)號查找學(xué)生,查找到之后打印出學(xué)生的具體信息。 4.根據(jù)學(xué)生的成績對學(xué)生信息進(jìn)行排序。 5.根據(jù)學(xué)號刪除學(xué)生信息。

示例:

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

//定義存放學(xué)生信息的結(jié)構(gòu)體類型
struct StuDentInfo
{
	char Name[20]; //姓名
	int number;    //學(xué)號
	char phone[20];//電話號碼
}; 

//全局變量區(qū)域
unsigned int  StuDentCnt=0; //記錄已經(jīng)錄入的全部學(xué)生數(shù)量

//函數(shù)聲明區(qū)域
void PrintStuDentInfoList(void);
void InputStuDentInfo(struct StuDentInfo*info);
void FindStuDentInfo(struct StuDentInfo*info);
void SortStuDentInfo(struct StuDentInfo*info);
void PrintStuDentInfo(struct StuDentInfo*info);

int main()
{
	struct StuDentInfo data[100]; //可以100位學(xué)生的信息
	int number;
	while(1)
	{
		PrintStuDentInfoList(); //打印功能列表
		scanf("%d",&number);
		printf("\n");
		switch(number)
		{
		case 1:
			InputStuDentInfo(data);
			break;
		case 2:
			FindStuDentInfo(data);
			break;
		case 3:
			SortStuDentInfo(data);
			break;
		case 4:
			PrintStuDentInfo(data);
			break;
		case 5:
			break;
		default:
			printf("選擇錯誤!\n\n");
			break;
		}
	}
 	return 0;
}

/*
函數(shù)功能: 打印學(xué)生管理系統(tǒng)的功能列表
*/
void PrintStuDentInfoList(void)
{
	printf("\n--------------學(xué)生管理系統(tǒng)功能列表----------------\n");
	printf("1. 錄入學(xué)生信息\n");
	printf("2. 根據(jù)學(xué)號查找學(xué)生信息\n");
	printf("3. 根據(jù)學(xué)號排序\n");
	printf("4. 打印所有學(xué)生信息\n");
	printf("5. 刪除指定的學(xué)生信息\n");
	printf("請選擇功能序號:");
}

/*
函數(shù)功能: 錄入學(xué)生信息
*/
void InputStuDentInfo(struct StuDentInfo*info)
{
	printf("輸入學(xué)生姓名:");
	scanf("%s",info[StuDentCnt].Name);
	printf("輸入學(xué)號:");
	scanf("%d",&info[StuDentCnt].number);
	printf("輸入電話號碼:");
	scanf("%s",info[StuDentCnt].phone);
	StuDentCnt++; //數(shù)量自增
}

/*
函數(shù)功能: 查找學(xué)生信息
*/
void FindStuDentInfo(struct StuDentInfo*info)
{
	int num,i;
	printf("輸入查找的學(xué)號:");
	scanf("%d",&num);
	for(i=0; i<StuDentCnt; i++)
	{
		if(info[i].number==num)
		{
			printf("信息查找成功,該學(xué)生的信息如下:\n");
			printf("姓名:%s\n",info[i].Name);
			printf("學(xué)號:%d\n",info[i].number);
			printf("電話號碼:%s\n",info[i].phone);
			printf("\n");
			break;
		}
	}
	if(i==StuDentCnt)
	{
		printf("----------%d學(xué)號不存在!---------\n",num);
	}
}

/*
函數(shù)功能: 根據(jù)學(xué)號排序
*/
void SortStuDentInfo(struct StuDentInfo*info)
{
	int i,j;
	struct StuDentInfo tmp; //保存臨時信息
	for(i=0; i<StuDentCnt-1; i++)
	{
		for(j=0;j<StuDentCnt-i-1;j++)
		{
			if(info[j].number>info[j+1].number)
			{
				tmp=info[j];
				info[j]=info[j+1];
				info[j+1]=tmp;
			}
		}
	}
}

/*
函數(shù)功能: 打印所有學(xué)生信息
*/
void PrintStuDentInfo(struct StuDentInfo*info)
{
	int i=0;
	printf("-----------所有學(xué)生的信息列表------------\n");
	for(i=0;i<StuDentCnt;i++)
	{
		printf("姓名:%s\n",info[i].Name);
		printf("學(xué)號:%d\n",info[i].number);
		printf("電話號碼:%s\n",info[i].phone);
		printf("\n");
	}
}

附:結(jié)構(gòu)體變量的存儲原理

1)結(jié)構(gòu)體數(shù)據(jù)成員對齊的意義

內(nèi)存是以字節(jié)為單位編號的,某些硬件平臺對特定類型的數(shù)據(jù)的內(nèi)存要求從特定的地址開始,如果數(shù)據(jù)的存放不符合其平臺的要求,就會影響到訪問效率。所以在內(nèi)存中各類型的數(shù)據(jù)按照一定的規(guī)則在內(nèi)存中存放,就是對齊問題。而結(jié)構(gòu)體所占用的內(nèi)存空間就是每個成員對齊后存放時所占用的字節(jié)數(shù)之和。

計算機(jī)系統(tǒng)對基本數(shù)據(jù)類型的數(shù)據(jù)在內(nèi)存中存放的限制是:這些數(shù)據(jù)的起始地址的值要求是某個數(shù)K的倍數(shù),這就是內(nèi)存對齊,而這個數(shù) K 就是該數(shù)據(jù)類型的對齊模數(shù)(alignment modulus)。這樣做的目的是為了簡化處理器與內(nèi)存之間傳輸系統(tǒng)的設(shè)計,并且能提升讀取數(shù)據(jù)的速度。

結(jié)構(gòu)體對齊不僅包括其各成員的內(nèi)存對齊(即相對結(jié)構(gòu)體的起始位置),還包括結(jié)構(gòu)體的總長度。

2)結(jié)構(gòu)體大小的計算方法和步驟

i. 將結(jié)構(gòu)體內(nèi)所有數(shù)據(jù)成員的長度值相加,記為 sum_a ;

ii. 將各數(shù)據(jù)成員為了內(nèi)存對齊,按各自對齊模數(shù)而填充的字節(jié)數(shù)累加到sum_a上,記為sum_b。

對齊模數(shù)是 #pragma pack 指定的數(shù)值與該數(shù)據(jù)成員自身長度相比較得到的數(shù)值較小者。該數(shù)據(jù)相對起始位置應(yīng)該是對齊模數(shù)的整數(shù)倍。

iii. 將和 sum_b 向結(jié)構(gòu)體模數(shù)對齊。

該模數(shù)則是 #pragma pack 指定的數(shù)值與結(jié)構(gòu)體內(nèi)最大的基本數(shù)據(jù)類型成員長度相比較得到的數(shù)值較小者。結(jié)構(gòu)體的長度應(yīng)該是該模數(shù)的整數(shù)倍。

數(shù)據(jù)類型自身對齊:

所謂“對齊在N上”,是指“存放的起始位置是%N = 0”.

總結(jié)

到此這篇關(guān)于C語言結(jié)構(gòu)體(struct)的文章就介紹到這了,更多相關(guān)C語言結(jié)構(gòu)體struct內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 淺析string 與char* char[]之間的轉(zhuǎn)換

    淺析string 與char* char[]之間的轉(zhuǎn)換

    與char*不同的是,string不一定以NULL('\0')結(jié)束。string長度可以根據(jù)length()得到,string可以根據(jù)下標(biāo)訪問。所以,不能將string直接賦值給char*
    2013-10-10
  • Qt圖形圖像開發(fā)之曲線圖表模塊QChart庫讀取/設(shè)置X軸的顯示區(qū)間

    Qt圖形圖像開發(fā)之曲線圖表模塊QChart庫讀取/設(shè)置X軸的顯示區(qū)間

    這篇文章主要介紹了Qt圖形圖像開發(fā)之曲線圖表模塊QChart庫讀取/設(shè)置X軸的顯示區(qū)間,需要的朋友可以參考下
    2020-03-03
  • 詳解C++中的增量運算符++和減量運算符--的用法

    詳解C++中的增量運算符++和減量運算符--的用法

    這篇文章主要介紹了C++中的增量運算符++和減量運算符--的用法,分為前綴情況和后綴情況來講,需要的朋友可以參考下
    2016-01-01
  • C++判斷一個點是否在圓內(nèi)的方法

    C++判斷一個點是否在圓內(nèi)的方法

    這篇文章主要為大家詳細(xì)介紹了C++判斷一個點是否在圓內(nèi)的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-05-05
  • VS2019安裝cbd調(diào)試器的實現(xiàn)步驟

    VS2019安裝cbd調(diào)試器的實現(xiàn)步驟

    本文主要介紹了VS2019安裝cbd調(diào)試器的實現(xiàn)步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-12-12
  • C語言數(shù)據(jù)結(jié)構(gòu)進(jìn)階之棧和隊列的實現(xiàn)

    C語言數(shù)據(jù)結(jié)構(gòu)進(jìn)階之棧和隊列的實現(xiàn)

    棧和隊列,嚴(yán)格意義上來說,也屬于線性表,因為它們也都用于存儲邏輯關(guān)系為 "一對一" 的數(shù)據(jù),但由于它們比較特殊,因此將其單獨作為一章,做重點講解
    2021-11-11
  • C++編程中刪除運算符與相等運算符的使用解析

    C++編程中刪除運算符與相等運算符的使用解析

    這篇文章主要介紹了C++編程中刪除運算符與相等運算符的使用解析,delete和==以及!=運算符的使用是C++入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2016-01-01
  • C++中傳值、傳地址和傳引用究竟有哪些區(qū)別

    C++中傳值、傳地址和傳引用究竟有哪些區(qū)別

    指針是一個變量,只不過這個變量存儲的是一個地址,指向內(nèi)存的一個存儲單元,而引用跟原來的變量實質(zhì)上是同一個東西,只不過是原變量的一個別名而已,這篇文章主要給大家介紹了關(guān)于C++中傳值、傳地址和傳引用究竟有哪些區(qū)別的相關(guān)資料,需要的朋友可以參考下
    2021-07-07
  • C/C++中使用列表框組件Qt?ListWidget

    C/C++中使用列表框組件Qt?ListWidget

    本文詳細(xì)講解了C/C++中使用列表框組件Qt?ListWidget的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-11-11
  • C語言 socketpair用法案例講解

    C語言 socketpair用法案例講解

    這篇文章主要介紹了C語言 socketpair用法案例講解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08

最新評論