結(jié)構(gòu)體的定義如下所示,struct為結(jié)構(gòu)體關(guān)鍵字,tag為結(jié)構(gòu)體的標(biāo)志,member-list為結(jié)構(gòu)體成員列表,其必須列出其所有成員;variable-list為此結(jié)構(gòu)體聲明的變量。在一般情況下,tag、member-list、variable-list這3部分至少要出現(xiàn)2個(gè)。
成都創(chuàng)新互聯(lián)公司專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都網(wǎng)站制作、網(wǎng)站建設(shè)、外貿(mào)網(wǎng)站建設(shè)、衡水網(wǎng)絡(luò)推廣、小程序制作、衡水網(wǎng)絡(luò)營(yíng)銷、衡水企業(yè)策劃、衡水品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營(yíng)等,從售前售中售后,我們都將竭誠(chéng)為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);成都創(chuàng)新互聯(lián)公司為所有大學(xué)生創(chuàng)業(yè)者提供衡水建站搭建服務(wù),24小時(shí)服務(wù)熱線:18982081108,官方網(wǎng)址:www.cdcxhl.com
結(jié)構(gòu)體的成員可以包含其他結(jié)構(gòu)體,也可以包含指向自己結(jié)構(gòu)體類型的指針,而通常這種指針的應(yīng)用是為了實(shí)現(xiàn)一些更高級(jí)的數(shù)據(jù)結(jié)構(gòu)如鏈表和樹等。如果兩個(gè)結(jié)構(gòu)體互相包含,則需要對(duì)其中一個(gè)結(jié)構(gòu)體進(jìn)行不完整聲明。
擴(kuò)展資料:
一、結(jié)構(gòu)體作用:
結(jié)構(gòu)體和其他類型基礎(chǔ)數(shù)據(jù)類型一樣,例如int類型,char類型,只不過結(jié)構(gòu)體可以做成你想要的數(shù)據(jù)類型,以方便日后的使用。
在實(shí)際項(xiàng)目中,結(jié)構(gòu)體是大量存在的,研發(fā)人員常使用結(jié)構(gòu)體來封裝一些屬性來組成新的類型。由于C語言內(nèi)部程序比較簡(jiǎn)單,研發(fā)人員通常使用結(jié)構(gòu)體創(chuàng)造新的“屬性”,其目的是簡(jiǎn)化運(yùn)算。
結(jié)構(gòu)體在函數(shù)中的作用不是簡(jiǎn)便,其最主要的作用就是封裝。封裝的好處就是可以再次利用。讓使用者不必關(guān)心這個(gè)是什么,只要根據(jù)定義使用就可以了。
二、結(jié)構(gòu)體的大小與內(nèi)存對(duì)齊:
結(jié)構(gòu)體的大小不是結(jié)構(gòu)體元素單純相加就行的,因?yàn)槲覀冎髁鞯挠?jì)算機(jī)使用的都是32bit字長(zhǎng)的CPU,對(duì)這類型的CPU取4個(gè)字節(jié)的數(shù)要比取一個(gè)字節(jié)要高效,也更方便。
所以在結(jié)構(gòu)體中每個(gè)成員的首地址都是4的整數(shù)倍的話,取數(shù)據(jù)元素時(shí)就會(huì)相對(duì)更高效,這就是內(nèi)存對(duì)齊的由來。每個(gè)特定平臺(tái)上的編譯器都有自己的默認(rèn)“對(duì)齊系數(shù)”(也叫對(duì)齊模數(shù))。
程序員可以通過預(yù)編譯命令#pragma pack(n),n=1,2,4,8,16來改變這一系數(shù),其中的n就是你要指定的“對(duì)齊系數(shù)”。
三、結(jié)構(gòu)體的規(guī)則:
1、數(shù)據(jù)成員對(duì)齊規(guī)則:結(jié)構(gòu)(struct)(或聯(lián)合(union))的數(shù)據(jù)成員,第一個(gè)數(shù)據(jù)成員放在offset為0的地方,以后每個(gè)數(shù)據(jù)成員的對(duì)齊按照#pragma pack指定的數(shù)值和這個(gè)數(shù)據(jù)成員自身長(zhǎng)度中,比較小的那個(gè)進(jìn)行。
2、結(jié)構(gòu)(或聯(lián)合)的整體對(duì)齊規(guī)則:在數(shù)據(jù)成員完成各自對(duì)齊之后,結(jié)構(gòu)(或聯(lián)合)本身也要進(jìn)行對(duì)齊,對(duì)齊將按照#pragma pack指定的數(shù)值和結(jié)構(gòu)(或聯(lián)合)最大數(shù)據(jù)成員長(zhǎng)度中,比較小的那個(gè)進(jìn)行。
3、結(jié)合1、2可推斷:當(dāng)#pragma pack的n值等于或超過所有數(shù)據(jù)成員長(zhǎng)度的時(shí)候,這個(gè)n值的大小將不產(chǎn)生任何效果。
參考資料來源:百度百科-結(jié)構(gòu)體
分析題意:
一、要定義兩個(gè)結(jié)構(gòu)體,一個(gè)是日期年月日,一個(gè)是員工。
二、程序包含三個(gè)功能:1、結(jié)構(gòu)數(shù)組的輸入。2、結(jié)構(gòu)數(shù)組的輸出。3、統(tǒng)計(jì)平均工資。根據(jù)編程習(xí)慣,三功能要寫成獨(dú)立函數(shù),方便擴(kuò)展和調(diào)用。
ps:員工數(shù)量定義成常量,也為編程習(xí)慣,便于修改。另外,日期驗(yàn)證我只寫了月份檢測(cè)給你參考。需擴(kuò)展,自行編寫函數(shù)驗(yàn)證。
#include stdio.h
#define M 3//最大員工數(shù)量
typedef struct date
{
int year;
int month;
int day;
}YMD;
typedef struct employee
{
int id;//工號(hào)
char name[20];//姓名
YMD date;//日期
int wage;
}EME;
void inputInfo(EME emes[]);//輸入
void outputInfo(EME emes[]);//輸出
float getAvg(EME emes[]);//求平均工資
int main()
{
EME emes[M];//員工結(jié)構(gòu)體數(shù)組
inputInfo(emes);
outputInfo(emes);
printf("平均工資:%f",getAvg(emes));
return 0;
}
void inputInfo(EME emes[])
{
int i;
for(i=0;iM;i++)
{
? printf("請(qǐng)輸入員工%d的信息:\n",i+1);
? printf("工號(hào):"),scanf("%d",emes[i].id);
? printf("姓名:"),scanf("%s",emes[i].name);
? printf("日期(分別輸入年月日,空格分割):"),scanf("%d%d%d",emes[i].date.year,emes[i].date.month,emes[i].date.day);
? if(emes[i].date.month12 || emes[i].date.month=0)//日期輸入的驗(yàn)證不通過時(shí),重新輸入,驗(yàn)證可單獨(dú)寫函數(shù),這里只做參考!
? {
? ? ? printf("輸入日期不符合,請(qǐng)重新輸入!\n\n"),i--;
? ? ? continue;
? }
? printf("工資:"),scanf("%d",emes[i].wage);
? printf("\n");
}
}
void outputInfo(EME emes[])
{
int i;
printf("所有員工的信息為:----------------------------\n");
for(i=0,printf("員工%d的信息:\n",i+1);iM;i++)
{
? printf("工號(hào):%d\n",emes[i].id);
? printf("姓名:%s\n",emes[i].name);
? printf("日期:%04d-%02d-%02d\n",emes[i].date.year,emes[i].date.month,emes[i].date.day);
? printf("工資:%d\n",emes[i].wage);
? printf("\n");
}
}
float getAvg(EME emes[])
{
int i;
float sum=0;
for(i=0;iM;i++)
? sum+=emes[i].wage;
return sum/M;
}
在另外一個(gè)函數(shù)里面使用的源代碼如下:
#include"stdio.h"
#include "conio.h" //-------添加這個(gè)頭文件,因?yàn)間etch()函數(shù)來自它,否則編譯會(huì)有警告
struct student ? /*定義結(jié)構(gòu)體*/
{
void main()
{
void data_in(struct student putin[]);
void data_out(struct student *p);
void data_pout(struct student *s1);
data_in(pers); ? ? ?/*調(diào)用指針輸入函數(shù)*/
data_out(sp); ? ? /*調(diào)用指針輸出函數(shù)*/
data_pout(sp); ? /*調(diào)用函數(shù)名輸出函數(shù)*/
getch();
}
擴(kuò)展資料
1、函數(shù)是C語言的基本組成元素,當(dāng)我們調(diào)用一個(gè)函數(shù)時(shí),需要明確函數(shù)名和實(shí)參列表。實(shí)參列表中的參數(shù)可以是常量、變量、表達(dá)式或者空,并且各參數(shù)之間要使用英文逗號(hào)分隔開來。
2、在C語言中,函數(shù)的定義是獨(dú)立的,一個(gè)函數(shù)不能定義在另一個(gè)函數(shù)內(nèi)部。但在調(diào)用函數(shù)時(shí),可以在一個(gè)函數(shù)中調(diào)用另一個(gè)函數(shù),這就是函數(shù)的嵌套調(diào)用。接下來我們通過一個(gè)案例來演示函數(shù)的嵌套調(diào)用。
#?includestdio.h
#?includemalloc.h
struct?stu????//結(jié)構(gòu)體
{
int?age;
float?score;
char?name[100];
};
void?shuru?(int?len,?stu?*?pArr)??
{
int?i;
for(i?=?0;?ilen;?i++)
{
printf("請(qǐng)輸入第%d個(gè)學(xué)生的信息\n",i+1);
printf("name?=?");
scanf("%s",pArr[i].name);
printf("age?=?");
scanf("%d",?pArr[i].age);
printf("score?=?");
scanf("%f",?pArr[i].score);
}
return;
}?
int?main(void)
{
int?len?,i;
struct?stu?*?pArr,t;
printf("請(qǐng)輸入學(xué)生的個(gè)數(shù):\n");
printf("人數(shù)=?");
scanf("%d",len);
pArr?=?(struct?stu?*)malloc(len?*?sizeof(struct?stu));??
shuru(len,?pArr);
for(i=0;?ilen;?i++)
{
if(pArr[i].score??pArr[i+1].score)
{
t?=?pArr[i+1];
pArr[i+1]?=?pArr[i];
pArr[i]?=?t;
}
}
i?=0;
printf("\n\n排序后的學(xué)生信息為\n\n");
for(i=0;?ilen;?i++)
{
printf("name?=?%s\n",pArr[i].name);
printf("age?=?%d\n",pArr[i].age);
printf("score?=?%f\n",pArr[i].score);
printf("\n\n");
}
return?0;
}
這樣就行了,你的排序還沒實(shí)現(xiàn), 仿照輸入的函數(shù)實(shí)現(xiàn)就OK
以前沒考慮過,剛才試了一下可以。不過不知道你說的是哪種定義,是定義一種結(jié)構(gòu)體的類型,還是定義一個(gè)結(jié)構(gòu)體的變量。反正下面這個(gè)函數(shù)是可以用的
void
abc()
{
struct
{
int
a;
int
b;
}dd;
struct
dd;
dd.a=10;
dd.b=20;
}
#include stdio.h
char *SubjectName[] = {"數(shù)學(xué)","物理","化學(xué)","生物","語文","外語","政治","歷史","體育","美術(shù)","音樂"}; //科目名稱列表 可調(diào)整順序
#define SUBJECT 2 //科目數(shù) 可設(shè)定 1 - 11門,超過11門時(shí)得添加上行科目名稱列表
#define STUDENTS_MAX 100 //最大可輸入的學(xué)生數(shù)量 根據(jù)實(shí)際情況調(diào)整
typedef struct student{char name[12]; float core[SUBJECT+1];} Student;//最長(zhǎng)姓名只許有五個(gè)漢字長(zhǎng)度,超長(zhǎng)會(huì)出錯(cuò) 改一下這個(gè)名字長(zhǎng)度或規(guī)定名字最長(zhǎng)5個(gè)字多余的不輸入也成
Student Stu[STUDENTS_MAX]; //結(jié)構(gòu)體數(shù)組 全局變量 雖可以不用全局的,要是你自己寫了很多函數(shù),都要訪問它們,不如就讓它們做全局變量的好
void main()
{
int total,i,j,k;
printf("請(qǐng)輸入學(xué)生總數(shù)[1-%d]:",STUDENTS_MAX);
scanf("%d",total);
if(totalSTUDENTS_MAX){printf("超出設(shè)計(jì)總數(shù)了");exit(-1);}
else if(total1){printf("沒有學(xué)生統(tǒng)計(jì)個(gè)屁呀"); exit(-1);}
printf("請(qǐng)輸入學(xué)生成績(jī),格式:\n\t姓名 ");
for(j=0;jSUBJECT;j++) printf("%s ",SubjectName[j]);
printf("\n");
for(i=0;itotal;i++)
{
Stu[i].core[SUBJECT]=0.0;//平均分
printf("No.%-3d ",i+1);
fflush(stdin); //清輸入緩沖區(qū)
scanf("%s %f",Stu[i].name,Stu[i].core[0]); //至少有一門科目的
for(j=1;jSUBJECT;j++) //其它科目 定義了多少就輸入多少
{
scanf("%f",Stu[i].core[j]);
Stu[i].core[SUBJECT] += Stu[i].core[j];
}
Stu[i].core[SUBJECT] /= SUBJECT; //平均分 只是求了沒有輸出
}
printf("\n不及格情況統(tǒng)計(jì):\n");
for(k=0,i=0;itotal;i++)
{
char putbuf[128],buf1[5];
int flag = 0;
strcpy(putbuf,Stu[i].name); //記下名字
for(j=0;jSUBJECT;j++)
if(Stu[i].core[j]60)
{
flag++;
strcat(putbuf," ");
strcat(putbuf,SubjectName[j]);//不及格的科目名稱
strcat(putbuf,":");
sprintf(buf1,"%4.1f",Stu[i].core[j]);strcat(putbuf,buf1);//分?jǐn)?shù)
}
if(flag)
{
printf("%s %d門不及格\n",putbuf,flag); //有不及格則輸出
k++; //統(tǒng)計(jì)不及格人數(shù)
}
}
if(!k)
printf("沒有不及格的學(xué)生");
else
printf("有不及格科目的學(xué)生個(gè)數(shù):%d",k);
}
//??吹接幸@類程序的,今天寫一個(gè),給大家參考,別天天上來要程序啊,仿照這個(gè)自己編吧
//程序在VC7.1下編譯通過,測(cè)試運(yùn)行正常