十、數組

来源:https://www.cnblogs.com/piaolaipiaoqu/archive/2023/11/16/17837546.html
-Advertisement-
Play Games

十、數組 1、數組的概念 1)引出數組 需求:學校為了統計學生的信息,需要設計一個程式,要求如下,一共有十個學員,要求依次輸入各位學員的學號,並將其列印出來。 #include <iostream> int main() { int studentId1, studentId2, studentId ...


十、數組

1、數組的概念

1)引出數組

需求:學校為了統計學生的信息,需要設計一個程式,要求如下,一共有十個學員,要求依次輸入各位學員的學號,並將其列印出來。

#include <iostream>

int main()
{
    int studentId1, studentId2, studentId3, studentId4, studentId5;
    std::cin >> studentId1;
    std::cin >> studentId2;
    std::cin >> studentId3;
    std::cin >> studentId4;
    std::cin >> studentId5;
    std::cout << "第一個學生的學號為" << studentId1 << std::endl;
    std::cout << "第二個學生的學號為" << studentId2 << std::endl;
    std::cout << "第三個學生的學號為" << studentId3 << std::endl;
    std::cout << "第四個學生的學號為" << studentId4 << std::endl;
    std::cout << "第五個學生的學號為" << studentId5 << std::endl;
}

問題描述:實際生活中,我們經常會需要處理多個具有相同性質的數據,比如100個員工的工資、10個學院的學號,這種情況下,依次申請多個變數變得不太現實或者太過繁雜,這種情況下,我們使用數組來解決這樣的問題。

2)數組的聲明

//數組聲明語法
數據類型 數組變數名稱[數組元素個數]{初始化值,初始化值...}

//示例:申請10個學員的學號
int studentId[10]{1,2,3,4}     //後面的沒初始化,預設為0。代表有10個元素

//示例:申請100個員工的工資
int salary[100]{}      //不初始化,預設為0

註:同一個數組,其數據類型是一樣的

3)數組的使用及遍歷

//輸入10個學生的學號,並且輸出
#include <iostream>

int main()
{
    int studentId[10]{};
    for (int i = 0; i < 10; i++)
    {
        std::cout << "請輸入第" << i << "個學生的學號:";
        std::cin >> studentId[i];
    }
    for (int i = 0; i < 10; i++)
    {
        std::cout << "第" << i << "個學生的學號為:";
        std::cout << studentId[i]<<std::endl;
    }
    //計算數組中元素個數
    std::cout << "studentId數組中有" << sizeof(studentId) / sizeof(int) << "個元素";
}

註:數組不初始化可以編譯,但是有可能使用記憶體中的垃圾數值

2)數組的本質

數組本質:數組的本質是按照所申請的數據類型,向操作系統申請了一段連續的記憶體空間,中間不能插入其他的變數

例:int age[6]在記憶體中是按照如下顯示的,總共占用4*6=26位元組



//計算數組的大小
#include <iostream>

int main()
{
    int studentId[10]{};
    std::cout<<"數組studentId的大小為"<<sizeof(studentId)<<std::endl;  //即4*10=40位元組

}

2、數組的應用

1)項目設計

需求:學校今天開學,要求等級每一位報道的學生,因此我們要設計一個程式,要求輸入學員的編號,並且列印出來。根據報名錶得知,今天來報道的學生有100位,但是不排除有個別學生因為飛機晚點、火山噴發等原因無法即使到達,但是無論如何,我們的報道工作還是要做的

#include <iostream>

int main()
{
	int studentId[100]{ 0 };
	int indexId{};  //已等級的學生信息
	while (indexId < 100)
	{
		std::cout << "輸入學號(輸入0查看已等級的學生信息):";
		std::cin >> studentId[indexId];
		if (studentId[indexId] == 0)
		{
			system("cls");
			for (int i = 0; i < indexId; i++)
			{
				std::cout << i << "號 學生學號" << studentId[i] << std::endl;
			}
		}
		else indexId++;       //,不是0,就代表學號。表示變成了下一個元素
	}

}

2)數組的另外一種聲明方式

//數組的另外一種聲明方式:不告訴數組的元素個數,但是對值進行賦值
變數類型 數組名[]{初始化,初始化}

//示例
int a[]{1,2,3};    //編譯器會自動將a聲明為只有一個有3個元素的數組
3、基於數組的迴圈

​ C++11之後的新用法:

1)案例:列印出一個數組的所有元素

//列印出一個數組的所有元素
#include <iostream>

int main()
{
	int studentId[]{ 1001,1002,1003,1004,1005,1006 };
	for (int i = 0; i < sizeof(studentId) / sizeof(int); i++)   //先計算元素個數
	{
		std::cout << "第"<<i<<"個學生的學號為:" << studentId[i] << std::endl;
	}
}

2)基於數組的迴圈

①基於數組的迴圈語法

//基於數組的迴圈語法
for(變數類型 變數名稱:數組名稱)
{
    迴圈內容;
}

//例
for(int i:studentId)   //給i賦予studentId數組中每個元素的值,
{
    迴圈內容;
}
//第一次i=studentId[0],第二次i=studentId[1],第三次i=studentId[3],依次。。。

//變數類型根據實際需求進行定義,例如char、auto都可以
for(auto 變數名稱:數組)
{
    迴圈內容;
}

②基於數組的迴圈用法

//基於數組的迴圈用法
#include <iostream>
int main()
{
	int studentId[]{ 9991,9992,9993,9994,9995,9996 };
	for (int i : studentId)
	{
		std::cout << i << std::endl;  //取元素時,不再使用studentId[i]取數據中的值,而是直接通過i
	}
}

③通過auto指定變數類型

//通過auto指定變數類型
#include <iostream>
int main()
{
	int studentId[]{ 9991,9992,9993,9994,9995,9996 };
	for (auto i : studentId)   //系統通過auto自動推斷出變數類型
	{
		std::cout << i << std::endl;
	}
}

④變數類型可以是任意類型

#include <iostream>

int main()
{
	int studentId[]{ 65,66,67,68,69,70 };
	for (char i:studentId)   //次數會進行強制類型轉化
	{
		std::cout << i<< std::endl;
	}
}

4、多維數組

1)引出多維數組:

需求:學校冬季要發大白菜,一共有3個班級,每個班級5個學員,要求統計這三個班所有學員的學號,並且列印出來。

//一維數組實現
#include <iostream>

int main()
{
	int studentId[15]{ };
	for (int x = 0; x < 15; x++)
	{
		std::cout << "第" << (x / 5) + 1 << "班,第" << (x % 5)+1 << "個學生" << std::endl;
	}

}

2)多維數組的定義

//多維數組聲明語法
類型 變數名稱[元素個數][元素個數]...[元素個數]{};

//示例
int studentId[3][5]{};                        //即可表示3個班,5個學員


//多維數組初始化示例
int studentId[3][5]
{
	{101,102,103,104,105},     //訪問第一個元素studentId[0][0]
	{201,202,203,204,205},
	{301,302,303,304,305}     //訪問第15個元素studentId[2][4]
}

案例:學校冬季要發大白菜,一共有3個班級,每個班級5個學員,要求統計這三個班所有學員的學號,並且列印出來。

#include <iostream>

//學院冬季發放大白菜,,一共3個班,每個班5個學院,要求統計這三個班所以學員的學號,並且列印出來
int main()
{
	int studentId[3][5]
	{
		{101,102,103,104,105},
		{201,202,203,204,205},
		{301,302,303,304,305}
	};
	for (int x = 0; x < 3; x++)
	{
		for (int y = 0; y < 5; y++)
		{
			std::cout << x+1 << "班第" << y+1 << "個同學的學號是:" << studentId[x][y] << std::endl;
		}
	}
}

3)多維數組的遍歷

除上述方式外,還可使用如下方式遍歷多維數組,但是需要單獨引入一個變數進行計數

#include <iostream>

//學院冬季發放大白菜,,一共3個班,每個班5個學院,要求統計這三個班所以學員的學號,並且列印出來
int main()
{
	int studentId[3][5]
	{
		{1,2,3,4,5},
		{1,2,3,4,5},
		{1,2,3,4,5}
	};
	for (int x=0;x<3;x++)
	{
		int count{};
		for (int y :studentId[x])    //y就表示student[x]中的值
		{
			count++;  //單獨引入一個變數進行計數
			std::cout << x + 1 << "班第" << count << "個同學的學號是:" <<y << std::endl;
		}
	}
}

4)多維數組的本質

本質:多維數組的本質也是向操作系統申請一塊連續的記憶體,一般來講是按照低緯度優先排序的方式來排序(可能因操作系統和編譯器不同而不同),而索引只是為了方便訪問對應的記憶體區域

示例:int studentId[3][5]在記憶體中的樣子如下

studentId[0][0] studentId[0][1] studentId[0][2] studentId[0][3] studentId[0][4]
studentId[1][0] studentId[1][1] studentId[1][2] studentId[1][3] studentId[1][4]
studentId[3][0] studentId[3][1] studentId[3][2] studentId[3][3] studentId[3][4]

4)數組的安全問題

​ 由於數組的本質是向操作系統申請了一塊記憶體,因此越界的數組將會訪問到不該訪問的地址,這種越界將會造成程式奔潰、BUG、錯誤,更可怕的是數組越界漏洞,可能會讓攻擊者拿到操作系統的控制權。

5、安全的數組(std::array容器)

1)std::array概念

​ 由於原生的數組存在著安全問題,使用不當會造成程式的漏洞,因此C++標準庫里提供了容器,後面詳細的進行容器學習,本次只簡單瞭解array這種容器如何實現類似數組的功能。

//array數組的語法
#include <array>   //需要先引入頭文件
std::array<變數類型,元素數量>變數名{初始化值};       //array的聲明

//案例
std::array<int,5>studentId;     //5個學員的學號

2)array使用

#include <iostream>
#include <array>  //引入頭文件

int main()
{
	std::array<int, 4>studentId{ 1001,1002,1003,1004 }; //聲明一個int類型的數組,包含4個元素,併進行初始化
	for (int x : studentId)        //遍曆數組,x表示數組中的每個元素
	{
		std::cout << x << std::endl;
	}
}

2)std::array的幾個常見用法

//std::array的幾個常見用法
std::array<int,5>studentId;    //聲明5個學員的學號
studentId.size();     //返回studentId擁有幾個元素
studentId.fill(250);  //將studentId數組的每個元素都設置為250
studentId.at(1);      //返回studentId[1]的內容
#include <iostream>
#include <array>

int main()
{
	std::array<int, 5>studentId;    //聲明5個學員的學號
	std::cout << "數組studentId擁有" << studentId.size() << "個元素" << std::endl;;     //返回studentId擁有幾個元素
	studentId.fill(250);  //將studentId數組的每個元素都設置為250
	for (int i : studentId)
	{
		std::cout << i << std::endl;
	}
	std::cout << "數組studentId的第4個值為" << studentId.at(3)<<std::endl;      //返回studentId[3]的內容
}

3)std::array的安全性

當使用【數組名.at】時,如果數組越界會直接報錯,便於尋找錯誤,但是原生數組對於越界訪問的數組不報錯。

4)array數組的比較

通過std::array可以比較兩個數組是否相同,但是原生數組無法進行比較

//數組的比較
#include <iostream>
#include <array>

int main()
{
	int classA[3]{ 123,456 };
	int classB[3]{ 123,456 };
	std::array<int, 5>studentIdA{123,456,789};    
	std::array<int, 5>studentIdB{123,456,789};    
	std::array<int, 5>studentIdC{121,456,789 };

	std::cout << (classA == classB) << std::endl;   //返回0,說明原生數組不可以進行比較
	std::cout << (studentIdA == studentIdB) << std::endl; //返回1
	std::cout << (studentIdA == studentIdC) << std::endl;  //返回0
}

6、std::vector容器

1)std::vector語法

//vector數組的語法
#include <vector>   //需要先引入頭文件
std::vector<數據類型>變數名{初始化值};       //vector的聲明

//案例
std::vector<int>studentId;     //聲明一個int類型的數組studentId,但是沒有元素
std::vector<int>studentId{1,2,3};     //聲明一個int類型的數組studentId,初始化3個元素
std::vector<int>studentId(5);     //註意是(),不是{},設置這個vector擁有5個元素
std::vector<int>studentId(5,100);     //註意是(),不是{},設置這個vector擁有5個元素,且初始值都為100

2)std::vector簡單使用

#include <iostream>
#include <vector>

int main()
{
	std::vector<int> studentId(5);  //告訴數組有5個元素,預設有初始值
	std::cout << "數組有:" << studentId.size() <<"個元素" << std::endl;
	std::cout << studentId.at(2) << std::endl;   //查看studentId[2]的值
	for (int x : studentId)
	{
		std::cout << x << std::endl;
	}
}

2)std::vector的新用法

  • 
    
    
    

註:array具備的有點,vector都具備

//向數組中動態添加值
#include <iostream>
#include <vector>

int main()
{	
	int userId;
	std::vector<int>studentId;  //定義vector數組

	do
	{
		std::cout << "請輸入學號:";
		std::cin >> userId;
		if (!userId) break;  //如果學號為0,直接退出
		studentId.push_back(userId);  //向數組中動態的添加值
	} while (true);  //因為已經有跳出迴圈機制,不需要再利用while的判斷

	for (int x : studentId)
	{
		std::cout << x << std::endl;
	}
}


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 作為一名全棧工程師,在日常的工作中,可能更側重於後端開發,如:C#,Java,SQL ,Python等,對前端的知識則不太精通。在一些比較完善的公司或者項目中,一般會搭配前端工程師,UI工程師等,來彌補後端開發的一些前端經驗技能上的不足。但並非所有的項目都會有專職前端工程師,在一些小型項目或者初創公... ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 在我們寫項目代碼時,應該更加專註於業務邏輯的實現,而把定式代碼交給js庫或工程化自動處理,而我想說的是,請求邏輯其實也是可以繼續簡化的。 你可能會說,用axios或fetch api就夠了啊,哪有什麼請求邏輯,那可能是你還沒有意識到這個問 ...
  • 需求:客戶的電腦都只能訪問內,伺服器可以訪問外網,客戶電腦使用的項目中用到了高德webapi2.0。10.200.31.45:32100是我們的web伺服器。 網上基本上都是對高德webapi1.4的配置方式,而web2.0有一些差別。 1.前端修改高德地圖的js應用 如果是index.html引入 ...
  • 最近做的幾個項目經常遇到這樣的需求,要在表格上增加一個自定義表格欄位設置的功能。就是用戶可以自己控制那些列需要展示。在幾個項目里都實現了一遍,每個項目的需求又都有點兒不一樣,迭代了很多版,所以抽時間把這個功能封裝了個組件:@silverage/table-custom,將這些差別都集成了進去,方便今... ...
  • 大綱 本文內容更多的是講講使用 vuex 的一些心得想法,所以大概會講述下麵這些點: Q1:我為什麼會想使用 vuex 來管理數據狀態交互? Q2:使用 vuex 框架有哪些缺點或者說副作用? Q3:我是如何在項目里使用 vuex 的? 初識 vuex 對於 vuex,有人喜歡,有人反感 喜歡的人覺 ...
  • 微服務是一種軟體架構策略,將應用程式分解為一組解耦的、自治的服務。採用微服務架構將改善整體性能和可擴展性,本文將概述微服務設計和實施的基本考慮因素。 ...
  • 重構有利於項目的健壯和精簡,平時要養成重構的好習慣,“小步快走”,儘量避免留著統一重構的思想,積累很多技術債後重構精力、時間成本很大,風險也會大很多 ...
  • 需求落地分散式應用服務 將需求轉化為分散式應用服務的過程可以按照以下步驟進行: 理解需求:首先,你需要仔細閱讀和理解業務需求。與相關的利益相關者(如業務分析師、產品經理等)進行溝通,確保你對需求的理解是準確的。 設計架構:根據需求,設計一個適合的分散式應用架構。這包括確定應用的組件和模塊,以及它們之 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...