嵌入式C語言筆記十七——構造數據類型

一.結構體:

1.類型定義:
struct 結構體名 {數據類型1 成員變量1;數據類型2 成員變量2;數據類型3 成員變量3;...
};struct student {char name[32];char sex;int age;int score;
};
2.結構體變量定義:

????????存儲類型 數據類型 變量名;

3.結構體元素初始化:

1.全部初始化:? ? ??

struct student stu = {"zhangsan", 'm', 18, 90};

2.局部初始化:

struct student stu = {.name = {"zhangsan"},    //沒有給定初值的元素都被賦值為0.score = 90,
};
4.結構體成員訪問:

????????. :結構體變量類型訪問成員變量 .

? ??? -> :結構體指針類型訪問成員變量 ->

????????結構體訪問成員變量最終的類型由成員變量的類型決定。

例:

#include <stdio.h>struct datetime {struct date {int year;int mon;int day;}d;struct time {int hour;int min;int sec;}t;
};struct student {char name[32];char sex;int age;int score;
};int main(void)
{struct datetime dt = {{2025, 7, 29}, {15, 9, 30},};struct datetime dt1 = {.t = {.hour = 15,.min = 10,},};struct student stu = {"zhangsan", 'm', 19, 100};struct student s = {.name = "lisi",.score = 80,};struct student *pstu = NULL;struct datetime *pdt = NULL;printf("%04d-%02d-%02d\n", dt.d.year, dt.d.mon, dt.d.day); // 輸出dt的日期和時間printf("%02d:%02d:%02d\n", dt.t.hour, dt.t.min, dt.t.sec);printf("%04d-%02d-%02d\n", dt1.d.year, dt1.d.mon, dt1.d.day); // 輸出dt1的日期和時間printf("%02d:%02d:%02d\n", dt1.t.hour, dt1.t.min, dt1.t.sec);printf("姓名:%s\n", stu.name); // 輸出stu的信息printf("性別:%c\n", stu.sex);printf("年齡:%d\n", stu.age);printf("成績:%d\n", stu.score);pstu = &s;printf("姓名:%s\n", pstu->name); // 通過指針輸出s的信息printf("性別:%c\n", pstu->sex);printf("年齡:%d\n", pstu->age);printf("成績:%d\n", pstu->score);pdt = &dt;printf("%04d-%02d-%02d %02d:%02d:%02d\n", pdt->d.year, pdt->d.mon, pdt->d.day, pdt->t.hour, pdt->t.min, pdt->t.sec); // 通過指針輸出dt的完整信息return 0;
}
從終端接收:
#include <stdio.h>
#include <string.h>struct student 
{char name[32];char sex;int age;int score;
};int main(void)
{	struct student s;struct student *pstu = NULL;char str[32] = {0};char tmpsex = 0;int tmpage = 0;int tmpscore = 0;pstu = &s;gets(pstu->name);scanf(" %c", &pstu->sex);scanf("%d", &pstu->age);scanf("%d", &pstu->score);printf("姓名:%s\n", s.name);printf("性別:%c\n", s.sex);printf("年齡:%d\n", s.age);printf("成績:%d\n", s.score);return 0;
}
5.結構體的存儲:

內存對齊:????????

struct student {char name[32];char sex;int age;int score; //32(name) + 1(sex) + 3(填充) + 4(age) + 4(score) = 44 字節
};

????????結構體成員必須存放在內存地址為自身類型長度整數倍的內存單元中,

????????結構體的大小必須為自身最大類型長度的整數倍。

6.結構體傳參:

1.傳值:

void fun(struct student tmp);

2.傳地址:

void fun(struct student *ptmp);
#include <stdio.h>
#include <string.h>struct student {char name[32];char sex;int age;int score;
};	struct student GetStuInfo(void)
{struct student tmp;gets(tmp.name);scanf(" %c", &tmp.sex);scanf("%d", &tmp.age);scanf("%d", &tmp.score);return tmp;
}int PutStuInfo(struct student tmp)
{	printf("姓名:%s\n", tmp.name);printf("性別:%c\n", tmp.sex);printf("年齡:%d\n", tmp.age);printf("成績:%d\n", tmp.score);return 0;
}void GetStuInfoByPoint(struct student *pstu)
{gets(pstu->name);scanf(" %c", &pstu->sex);scanf("%d", &pstu->age);	scanf("%d", &pstu->score);return;
}void PutStuInfoByPoint(struct student *pstu)
{printf("姓名:%s\n", pstu->name);printf("性別:%c\n", pstu->sex);printf("年齡:%d\n", pstu->age);printf("成績:%d\n", pstu->score);return;
}int main(void)
{struct student ret;memset(&ret, 0, sizeof(ret));    //初始化,內存置位GetStuInfoByPoint(&ret);PutStuInfoByPoint(&ret);#if 0ret = GetStuInfo();PutStuInfo(ret);
#endifreturn 0;
}

????????傳地址更好,因為實參將8字節拷貝給形參,避免結構體大空間的拷貝。

7.結構體數組:

????????格式:數據類型 數組名[元素個數];

8.結構體數組初始化:
struct student s[3] = {{"zhangsan", 'm', 19, 100},{"lisi", 'f', 18, 90},{"wanger", 'm', 19, 60},
};struct student s[3] = {[1] = {.name = "zhangsan",.score = 90,},
};
9.結構體數組傳參:
int fun(struct student *pstu, int len);

二.共用體:

1.共用體也稱為聯合體:

????????共用體每個成員變量的空間共享的,

????????結構體每個成員變量的空間是獨立的,

????????多用于函數傳參使用。

2.數據類型定義:
union 共用體名 {數據類型1 成員變量1;數據類型2 成員變量2;數據類型3 成員變量3;...
};
3.使用共用體判斷內存大小端:

????????內存低地址存放低數據位,內存高地址存放高數據位,內存小端

????????內存低地址存放高數據位,內存高地址存放低數據位,內存大端。

#include <stdio.h>union s {char a;int b;
};int main(void)
{union s s1;s1.b = 1;if(s1.a){printf("小端存儲\n");}else {printf("大端存儲\n");}#if 0int Num = 0;char *p = NULL;Num = 0x11223344;p = (char *)&Num;if (0x11 == *p){printf("大端存儲\n");}else if (0x44 == *p){printf("小端存儲\n");}
#endifreturn 0;
}

三.枚舉:

1. 枚舉定義一些枚舉常量。

2.定義形式:

enum 枚舉類型 {常量1,常量2,常量3,...
};

3.特性:

????????枚舉常量均為int類型,且第一個枚舉常量的值默認為0,后續枚舉常量的值總是前一個常量的
值+1,

????????枚舉常量可以在定義時被賦值。

例:

#include <stdio.h>enum weekday {MONDAY = 1,TUESDAY,WEDNESDAY,THURDAY,FRIDAY,SATURSDAY,SUNDAY,
};int main(void)
{enum weekday day;printf("請輸入今天是周幾:\n");scanf("%d", (int *)&day);switch (day){case MONDAY:printf("尾號1和6限行\n");break;case TUESDAY:printf("尾號2和7限行\n");break;case WEDNESDAY:printf("尾號3和8限行\n");break;case THURDAY:printf("尾號4和9限行\n");break;case FRIDAY:printf("尾號5和0限行\n");break;case SATURSDAY:case SUNDAY:printf("不限行\n");}return 0;
}

四.練習:

1.計算并顯示一個給定日期在當年是第幾天,以及該年還剩余多少天:
#include <stdio.h>struct date {int year;int mon;int day;
};int GetDate(struct date *pday)
{scanf("%d-%d-%d", &pday->year, &pday->mon, &pday->day);return 0;
}int IsLeepYear(int tmpyear)
{if (((0 == tmpyear % 4) && (tmpyear % 100 != 0)) || (0 == tmpyear % 400)){return 1;}return 0;
}int GetDayOfYear(struct date *pday)
{int i = 0;int sum = 0;for (i = 1; i < pday->mon; i++){switch (i){case 1:case 3:case 5:case 7:case 8:case 10:case 12:sum += 31;break;case 4:case 6:case 9:case 11:sum += 30;break;case 2: sum += (IsLeepYear(pday->year) ? 29 : 28);}}sum += pday->day;return sum;
}int GetLeftDayOfYear(struct date *pday)
{int total = 0;if (IsLeepYear(pday->year)){total = 366;}else {total = 365;}return total - GetDayOfYear(pday);
}int main(void)
{struct date day;int cnt = 0;GetDate(&day);cnt = GetDayOfYear(&day);printf("%04d-%02d-%02d為該年的第%d天\n", day.year, day.mon, day.day, cnt);cnt = GetLeftDayOfYear(&day);printf("該年剩余%d天\n", cnt);return 0;
}
2.單詞順序反轉,并保持內部的順序不變(不使用逆序算法):
#include <stdio.h>
#include <string.h>int strswap(char *phead, char *ptail)
{char tmp = 0;while (phead < ptail){tmp = *phead;*phead = *ptail;*ptail = tmp;phead++;ptail--;}return 0;
}int wordswap(char *pstr)
{char *pstart = NULL;char *pend = NULL;//先對整體交換strswap(pstr, pstr+strlen(pstr)-1);pstart = pstr;while (1){pend = strchr(pstart, ' '); //使用strchr找到下一個空格if (pend != NULL){strswap(pstart, pend-1); //如果找到了空格,就反轉這個單詞}else {strswap(pstart, pstart + strlen(pstart) - 1);break;}pstart = pend + 1;}#if 0pstart = pstr;pend = pstart;while (*pend != '\0'){pend = pstart;while (*pend != '\0' && *pend != ' '){pend++;}strswap(pstart, pend-1);pstart = pend + 1; //合法但危險}
#endifreturn 0;
}int main(void)
{char str[256] = {0};gets(str);wordswap(str);printf("str = %s\n", str);return 0;
}
3.學生信息錄入 + 輸出:
#include <stdio.h>struct student {char name[32];char sex;int age;int score;
};int GetAllStuInfo(struct student *pstu, int len)
{int i = 0;int n = 0;printf("請輸入學生個數:\n");scanf("%d", &n);getchar(); // 讀取掉輸入個數后的回車,避免后續 gets 被跳過for (i = 0; i < n; i++){gets(pstu->name);scanf(" %c", &pstu->sex);scanf("%d", &pstu->age);scanf("%d", &pstu->score);pstu++;
#if 0gets((pstu+i)->name);scanf(" %c", &(pstu+i)->sex);scanf("%d", &(pstu+i)->age);scanf("%d", &(pstu+i)->score);//		gets(pstu[i].name);    //\n會導致后續輸入亂掉scanf("%s", pstu[i].name);scanf(" %c", &pstu[i].sex);scanf("%d", &pstu[i].age);scanf("%d", &pstu[i].score);
#endifgetchar();}return n;
}int PutAllStuInfo(struct student *pstu, int len)
{int i = 0;for (i = 0; i < len; i++){printf("姓名:%s\n", pstu[i].name);printf("性別:%c\n", pstu[i].sex);printf("年齡:%d\n", pstu[i].age);printf("成績:%d\n", pstu[i].score);}return 0;
}int main(void)
{struct student s[100]; // 最多int curlen = 0; // 實際curlen = GetAllStuInfo(s, 100);PutAllStuInfo(s, curlen); // 接多少輸出多少return 0;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/95892.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/95892.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/95892.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

深入實踐G1垃圾收集器調優:Java應用性能優化實戰指南

深入實踐G1垃圾收集器調優&#xff1a;Java應用性能優化實戰指南 一、技術背景與應用場景 隨著微服務和海量并發請求的普及&#xff0c;Java應用在生產環境中對低延遲和高吞吐的需求日益顯著。傳統的CMS和Parallel GC 在大內存場景下常出現Full GC 停頓時間長、吞吐下降等問題…

【JobScheduler】Android 后臺任務調度的核心組件指南

JobScheduler 是 Android 平臺上原生支持在直接啟動模式&#xff08;Direct Boot Mode&#xff09;下執行任務的調度器。 相比 WorkManager 需要復雜的配置才能勉強支持直接啟動&#xff0c;JobScheduler 在這方面有著天生的優勢和明確的 API 支持。如果你面臨的硬性要求是必須…

c# 調用basler 相機

目錄 一聯合halcon&#xff1a; 二 c# 原生 一聯合halcon&#xff1a; 環境配置 下載安裝pylon軟件 下載安裝halcon 創建 winform項目 test_basler 添加引用 打開pylon可以連接相機 可以看到我的相機id為23970642 &#xff08; c#聯合halcon的基礎教程&#xff08;案例…

《2025年AI產業發展十大趨勢報告》四十六

《2025年AI產業發展十大趨勢報告》四十六隨著科技的迅猛發展&#xff0c;人工智能&#xff08;AI&#xff09;作為引領新一輪科技革命和產業變革的戰略性技術&#xff0c;正逐步滲透到各個行業和領域&#xff0c;成為推動經濟社會發展的重要引擎。2023年&#xff0c;生成式AI的…

c++ 雜記

1. 為什么返回*this?2. 3. 友元函數的使用&#xff1a;需要頭文件中類內外聲明&#xff0c;cpp文件中實現定義哦// Sales_data.h #ifndef SALES_DATA_H #define SALES_DATA_H#include <string>class Sales_data {std::string bookNo;int units_sold 0;double revenue …

PDF文件基礎-計算機字體

計算機字體的原理包含了字符編碼、字形渲染和字體文件存儲三個關鍵技術。 字符編碼負責將每個字符映射到一個唯一的數字碼&#xff1b;字形渲染則將這些數字碼轉換成屏幕或紙張上可識別的圖形&#xff1b;字體文件存儲則包含了字符的編碼、圖形描述信息以及字體的其他屬性&…

華為IP(9)

OSPF的基本配置OSPF路由計算前言&#xff1a;1)同一區域內的OSPF路由器擁有完全一致的LSDB&#xff0c;在區域內部&#xff0c;OSPF采用SPF算法完成路由計算。2&#xff09;隨著網絡規模不斷擴大&#xff0c;路由器為了完成路由計算所消耗的內存、CPU資源也越來越多。通過區域劃…

java.nio.file.InvalidPathException異常

一.問題概述 本人在ubuntu22.04的操作系統上&#xff0c;運行java程序時創建一個文件時&#xff0c;由于文件名稱中包含了中文&#xff0c;所以導致了程序拋出了java.nio.file.InvalidPathException的異常。 java.nio.file.InvalidPathException: Malformed input or input co…

Next系統總結學習(一)

下面我按題號逐條 詳細 解釋并給出示例與最佳實踐。為便于閱讀&#xff0c;我會同時給出關鍵代碼片段&#xff08;偽代碼/實用例子&#xff09;&#xff0c;并指出常見坑與解決方案。 1. 你是如何理解服務端渲染&#xff08;SSR&#xff09;的&#xff1f;它的核心工作流程是怎…

房屋安全鑒定需要什么條件

房屋安全鑒定需要什么條件&#xff1a;專業流程與必備要素解析房屋安全鑒定是保障建筑使用安全的重要環節&#xff0c;它通過對建筑結構、材料性能及使用狀況的全面評估&#xff0c;為房屋的安全使用、改造或維護提供科學依據。隨著城市建筑老化及自然災害頻發&#xff0c;房屋…

現代C++:現代C++?

C語言正在走向完美&#xff0c;所以&#xff0c;C語言值得學習&#xff08;甚至研究&#xff09;&#xff0c;這些知識可以成為一切編程的基礎。然而在實踐中&#xff0c;不必全面的使用C語言的各種特性&#xff0c;而應根據工程項目的實際情況&#xff0c;適當取舍&#xff08…

【C++】哈希表實現

1. 哈希概念 哈希(hash)又稱散列&#xff0c;是?種組織數據的方式。從譯名來看&#xff0c;有散亂排列的意思。本質就是通過哈希 函數把關鍵字Key跟存儲位置建立一個映射關系&#xff0c;查找時通過這個哈希函數計算出Key存儲的位置&#xff0c;進行快速查找 1.1 直接定址法…

ai 玩游戲 llm玩街霸 大模型玩街霸 (3)

1. 開源代碼地址&#xff1a; https://github.com/OpenGenerativeAI/llm-colosseum 2. 架構&#xff1a; 3. 圖片&#xff1a; 4. 感覺還是下面的步驟&#xff1a; a. 實時理解游戲當前環境&#xff0c;英雄角色&#xff0c;英雄狀態 b. 根據當前狀態感知&#xff0c;生成英雄…

2025年滲透測試面試題總結-59(題目+回答)

安全領域各種資源&#xff0c;學習文檔&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各種好玩的項目及好用的工具&#xff0c;歡迎關注。 目錄 一、SQL注入全解 二、XSS與文件漏洞 三、服務端漏洞專題 四、職業經驗與能力評估 1、注入攻擊原理是什么…

GPT系列--類GPT2源碼剖析

無需多言&#xff0c;大家應該都用過了&#xff0c;如今都更新到GPT-5了。1. GPT-1回到2018年的NLP&#xff0c;神仙打架&#xff0c;BERT與GPT不分先后。GPT是“Generative Pre-Training”的簡稱&#xff0c;生成式的預訓練。BERT和GPT肯定是GPT難訓練&#xff0c;引用量也是B…

這是一款沒有任何限制的免費遠程手機控制手機的軟件

這是一款沒有任何限制的免費遠程手機控制手機的軟件支持安卓和蘋果1.安裝1.1被控制端安裝airdroid1.2控制端air mirror2.登錄賬號控制端和被控制端登錄同一個賬號3.控制打開控制端軟件選擇要控制的機器直接點“遠程控制“

Observability:更智能的告警來了:更快的分診、更清晰的分組和可操作的指導

作者&#xff1a;來自 Elastic Drew Post 探索 Elastic Stack 告警的最新增強功能&#xff0c;包括改進的相關告警分組、將儀表盤鏈接到告警規則&#xff0c;以及將調查指南嵌入到告警中。 在 9.1 版本中&#xff0c;我們對告警進行了重大升級&#xff0c;幫助 SRE 和運維人員更…

數智之光燃盛景 共同富裕創豐饒

8月29日&#xff0c;2025數博會“一帶一路”國際大數據產業發展暨數智賦能新時代、共同富裕向未來的會議在貴陽國際生態會議中心隆重舉行。作為全球大數據領域的重要盛會&#xff0c;此次活動吸引了來自聯合國機構、國際組織、科研院所、知名企業等社會各界的百余位代表&#x…

【網絡編程】recv函數的本質是什么?

一、為什么說recv函數的本質是 “copy”&#xff1f; recv是用于從網絡連接&#xff08;或其他 IO 對象&#xff09;接收數據的函數&#xff0c;它的核心動作不是 “從網絡上拉取數據”&#xff0c;而是 “把已經到達內核緩沖區的數據復制到用戶程序的緩沖區”。 具體流程拆解&…

JSP程序設計之輸入/輸出對象 — out對象

目錄1、out對象概述2.實例&#xff1a;out對象方法運用輸入/輸出對象&#xff0c;可以控制頁面的輸入和輸出&#xff0c;用于訪問與所有請求和響應有關的數據&#xff0c;包括out、request和response對象。 1、out對象概述 out對象是JspWriter類的一個實例&#xff0c;是一個…