四、基本數據類型和計算(三)

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

四、基本數據類型和計算(三) 1、枚舉變數 1)通過案例體現枚舉類型的作用 ​ 假設要為我們的游戲裝備設置稀有度屬性,應該如何設計 裝備級別 變數名 普通 normal 高級 high 稀有 rare 史詩 epic 傳說 legend 神話 myth 不使用枚舉變數,使用常量方式設置 #inclu ...


四、基本數據類型和計算(三)

1、枚舉變數

1)通過案例體現枚舉類型的作用

​ 假設要為我們的游戲裝備設置稀有度屬性,應該如何設計

裝備級別 變數名
普通 normal
高級 high
稀有 rare
史詩 epic
傳說 legend
神話 myth

不使用枚舉變數,使用常量方式設置

#include  <iostream>
#define Normal 0  //普通裝備
#define High 1   //高級裝備
#define Rare 2   //稀有裝備
#define Epic 3   //史詩裝備
#define Legend 4   //傳說裝備
#define myth  5   //神話裝備

int main()
{
	short weaponLv;
	
	short weaponALv = Rare;  //稀有
	short weaponBLv = myth;  //神話

	std::cout << "裝備A的等級為:" << weaponALv << std::end;;
	std::cout << "裝備B的等級為:" << weaponBLv << std::endl;

}

2)枚舉變數定義及聲明

​ 電腦中沒有這種類型,我們自定義一種數據類型,就叫做枚舉類型

定義 enum class 類型名稱:基本類型{選項1,選項2};
聲明 類型名稱 變數名稱;
示例 如下

註:基本類型只能是整數類型,如果不寫預設為int類型,整數類型用來說明大括弧中定義的變數是什麼類型。

//通過枚舉類型設置裝備的稀有程度
#include <iostream>
int main() {

	enum class EquipLv : int {     //可以將int替換為其他整數類型,如float
		normal = 10,   armyA = normal,//普通        //若不初始化,預設為0
		high,          armyB = high,//高級          //從上之下自動遞增,此處high為11
		rare,          armyC = rare,//稀有
		epic,          armyD = epic,//史詩
		legend,        armyE = legend,//傳奇
		myth = 100,    armyS = normal//神話
	};

	EquipLv weaponAlv{ EquipLv::normal }; //定義裝備A等級
	EquipLv weaponBlv{ EquipLv::myth }; //定義裝備B等級

	short diff = (int)weaponAlv - (int)weaponBlv;       //如果不強制類型轉化,無法直接進行計算
	std::cout << "weaponAweaponB裝備的等級差為:" << diff << std::endl;

	weaponAlv = EquipLv::rare; //重新賦值。修改裝備A的等級
	std::cout << "裝備A的等級修改為:" << int(weaponAlv)<<std::endl;
}

2)枚舉類型註意點

①枚舉類型可以提高代碼的可讀性和安全性

②枚舉類型預設是int類型

③枚舉類型成員只能是整數類型

④枚舉類型和其他類型轉化需要強制轉化

⑤預設情況下,枚舉類型的下一項的初始值是上一項的初始值+1

2、自定義變數名稱

將C/C++中已有的變數進行改名,可以將一些特別長的變數名進行改名

語法 含義 缺點
#define A TypeName 以後代碼中的A可以被替換為TypeName 簡單替換
typedef TypeName A; 以後TypeName類型的名字可以用A替換 不直觀
using A=TypeName; 以後TypeName類型的名字可以用A替換 可以實現一些信特性

#include <iostream>
#define 整數 int   //自定義變數名稱方法一
#define elong long ////自定義變數名稱方法一,將long替換為elong

int main() {
	整數 num{ 100 };    //編譯器編譯時,會將所有的"整數"替換為int
    
	typedef unsigned xxx;      //自定義方法名稱二,即將unsigned類型替換為xxx
	xxx A{200};
    
    using ellong = long long;   //自定義變數名稱方法三,將long long替換為ellong,
	ellong a{50};
    
    using elllong = elong elong; //此時的一個long已通過elong替換

	std::cout << num << char(10);
	std::cout << A << char(10);
    std::cout << a << char(10);

}

3、命名空間

1)命名空間定義

​ 為了將需要用的東西放到一起,例如: 糧食倉庫::大米;糧食倉庫:小麥

namespace namespace_name {
   // 代碼聲明
}

2)命名空間使用

使用方式 語法 備註
方式一 std::cout 使用限定符::
方式二 using std::cout;cout<<"再不用std"; 使用using,只有cout不需要寫命名空間std
方式三 using namespace std; 命名空間所有內容都可進行使用,不推薦
//命名空間的定義和使用
#include <iostream>

namespace lGame {
	int HP{ 1000 };
	int MP{ 1000 };
	int lv{ 1 };
	namespace Weapon {              //命名空間的內嵌定義
		int damage{ 3000 };
		namespace WeaponInfo {
			int lv = lGame::lv;
		}
	
	}
}

int main() {
	using std::cout;       //命名空間第一種使用方式
	using namespace std;   //命名空間第二種使用方式
	using lGame::HP;       //命名空間第三種使用方式
    
    std::cout<<"用戶血量為"<<lGame::HP<<std::endl;   //命令空間的使用
    std::cout<<"用戶血量為"<<HP<<std::endl;

	int c = lGame::Weapon::damage;        //命名空間內嵌使用
	cout << c;         //此時不需要在寫cout

}

3)命名空間註意事項

①不能將命名空間定義放在函數體內

②可以在一個命名空間內嵌入另一個命名空間

③子級命名空間調用父級命名空間依然需要限定符::

4、變數的生命周期

​ 變數的聲明周期,本質上為記憶體的生命周期。即記憶體的申請和釋放

#include <iostream>

int a{ 100 };      //沒有在代碼塊內,屬於全局變數,程式結束則變數結束
int main()
{
	int a{ 160 };
	{
		int a{ 350 };     //在代碼快中可以用::a來調用全局變數a{100};
		{
			char a = 'A';
			std::cout << a<<std::endl;  //輸出A
			std::cout << ::a << std::endl; //輸出100
		} 
		std::cout << a << std::endl;  //輸出350  //變數就近往上原則,聲明周期原則,通常找距離它最近的值
	}
	std::cout << a  <<std::endl;  //輸出160

}

1)註意事項

①代碼塊中的變數的生命周期從聲明開始,知道這個代碼塊結束

②聲明在代碼開始前的變數叫做全局變數,全局變數的生命從程式運行開始,知道程式退出

③在變數名衝突的情況下,採用就近原則

④要訪問名稱衝突的全局變數,可以使用限定符::來訪問

⑤變數哪裡用哪裡聲明

5、位運算之異或運算

1)異或運算關係:相同為0,不同為1

2)作用:加解密

3)異或運算最大特征:具有還原功能,只要其中有一個值發生了變化,都可通過相互異或檢測出來。

即a^b=c; b^c=a; c^a=b;

4)案例:

​ 麟江湖是一個單機游戲,其中變數diamond代表鑽石,變數vip_exp代表累計鑽石消費數。設計一個演算法,使得能夠發現,用戶使用單機修改器修改了鑽石或者累計鑽石數這樣的做必須行為。

思路:將鑽石diamond和累計消費數vip_exp放在a、b的位置,只要將兩個值進行異或操作生成C,只要使用C和其中任何一個值異或計算,就可判斷出第三個值是否發生改變,進而檢測出用戶有無作弊

#include <iostream>

int main() {
	unsigned int diamond{ 6000 }; //鑽石數量
	unsigned int vip_exp{ 80000 }; //VIP充值經驗
	unsigned xbase = diamond ^ vip_exp; 

	std::cout << "修改鑽石數量:";
	std::cin >> diamond;
	std::cout << "修改累計消費:";
	std::cin >> vip_exp;
	//模擬檢測
	unsigned realDiamond = xbase ^ vip_exp;
	unsigned realvip_exp = xbase ^ diamond;
	std::cout << "你應該的鑽石數量為:" << realDiamond << std::endl;
	std::cout << "你應該的累計消費為:" << realvip_exp << std::endl;

}

只要修改一個值,就可還原出來原來的數據;如果修改兩個值,值雖然不會還原出來,但是也可以確認用戶作弊了

7、自定義數據類型(結構體)

​ 自己創建數據類型,解決基本數據類型解決不了的問題。

基本數據類型問題:假如要創建一個汽車管理系統,要定義多個品牌的車,每個品牌的屬性都不一樣,若只用基本數據類型,就需要將每種品牌的車都進行定義,很麻煩

#include <iostream>

int main()
{
	int wheel {19};
	unsigned price{ 100000 };
	char logo{ 'B' };
	unsigned gls{ 100 };

	std::cout << "車輛商標:" << logo << "  車輪大小:" << wheel << "  車輛售價:" << price << std::endl;

	int wheelA{ 20 };
	unsigned priceA{ 900000 };
	char logoA{ 'C' };
	unsigned glsA{ 200 };

	std::cout << "車輛商標:" << logoA << "  車輪大小:" << wheelA << "  車輛售價:" << priceA << std::endl;
}

1)結構體定義及使用

//結構體的定義方法
struct 名稱
{
    類型 名稱;
}
//結構體類型使用
結構體名稱 變數名{初始化值};

//簡單案例
struct CAR      //結構體定義
{
		char logo{ 'X'};       
		unsigned short whell{ 19 };
		unsigned price{ 90000 };
};

CAR carA{'A',20,80000} //結構體變數初始化
std::cout<<carA::log<<std::endl;  //結構體變數的使用

3)結構體使用

#include <iostream>

int main() {
	struct Car            //結構體類型的定義
	{
		char logo{ 'X' };
		unsigned short whell{ 19 };
		unsigned price{ 90000 };
	};

	Car carA{ 'X',25,5000000 };    //結構體類型變數的定義及初始化
	Car carB{ 'Y',30,4000000 };
	Car carC{ 'Z',15,200000 };

	//結構體變數的使用
	std::cout << "A車輛logo:" << carA.logo << ",A車輛輪子:" << carA.whell << ",A車輛售價:" << carA.price << std::endl;
	std::cout << "B車輛logo:" << carB.logo << ",B車輛輪子:" << carB.whell << ",B車輛售價:" << carB.price << std::endl;
	std::cout << "C車輛logo:" << carC.logo << ",C車輛輪子:" << carC.whell << ",C車輛售價:" << carC.price << std::endl;
}

2)結構體的本質

①結構體的本質是按照我們自己定義的方式定義一塊連續的記憶體的結構

②聲明一個結構體變數的本質是向電腦申請一塊記憶體,而這塊記憶體的大小,至少是我們定義的結構成員需要占用的記憶體之和(某些情況記憶體會虛高)

③使用結構體,則是按照我們定義好的方式從這塊記憶體讀取和寫入數據

8、案例:設計游戲角色數據

​ 為麟江湖游戲設計角色的基本屬性,角色包括一下屬性:

①等級(1-100級)

②門派(武當、峨眉、少林、葵花、唐門)

③武器(0-15階,0-15強化),護甲(0-15階,0-15強化),首飾(0-15階,0-15強化)

④經驗值 ⑤生命值 ⑥生命最大值 ⑦內力值 ⑧內力最大值 ⑨坐標 ⑩金幣 ⑪ 鑽石 ⑫ 幸運值 ⑬ 累計消費

#include <iostream>

//門派定義
enum class SCHOOL :char {
	wudang,
	emei,
	kuihua,
	tangmen,
	shaolin,
};

//裝備定義
struct Equip
{
	unsigned char lv{ 0 }; //裝備等級
	unsigned char ev{ 0 }; //裝備強化等級
};

//角色狀態定義
struct RoleState
{
	int value{ 1000 }; //角色生命值
	unsigned maxValue{ 1000 }; //角色最大生命值
};

//角色定義
struct Role {
	unsigned char lv{ 1 }; //角色等級
	SCHOOL school{ SCHOOL::tangmen };  //門派
	Equip  weapon{ 1,1 }; //武器等級、強化等級
	Equip  army{ 1,10 };  //布甲等級、強化等級
	Equip neck{ 1,10 };    //
	long long exp{ 0 };
	RoleState HP{ 1000,1000 }; //角色血量、最大生命值
	RoleState MP{ 1000,1000 }; //角色藍量、最大藍量
	unsigned x{ 500 }; //橫坐標
	unsigned y{ 500 }; //縱坐標
	unsigned Money{ 1000 }; //金幣數
	unsigned Diamond{ 100 }; //鑽石數
	unsigned char luck{ 2 };//幸運值
	unsigned vip_exp{ 0 }; //充值經驗

};

int main() {

	Role user;
	std::cout << "生命:" << user.HP.value << "/" << user.HP.maxValue << std::endl;
	std::cout << "內力:" << user.MP.value << "/" << user.MP.maxValue << std::endl;
	std::cout << "坐標:【" << user.x << "】【" << user.y << "】" << std::endl;

}


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

-Advertisement-
Play Games
更多相關文章
  • SciPy的linalg模塊是SciPy庫中的一個子模塊,它提供了許多用於線性代數運算的函數和工具,如矩陣求逆、特征值、行列式、線性方程組求解等。 相比於NumPy的linalg模塊,SciPy的linalg模塊包含更多的高級功能,並且在處理一些特定的數值計算問題時,可能會表現出更好的性能。 1. ...
  • 深入理解CAS 什麼是CAS 為什麼要學CAS:大廠你必須深入研究底層!有所突破! java層面的cas >compareAndSet compareAndSet(int expectedValue, int newValue) 期望並更新,達到期望值就更新、否則就不更新! package org. ...
  • 思想 DAO(Data Access Object)數據訪問對象,是我們在做結構化資料庫訪問的時候傳輸的對象,通過這個對象我們可以與資料庫中的表建立映射關係 DTO(Data Transfer Object)是我們在與前端進行數據交換時傳遞的對象 為什麼需要設置這這兩種對象呢? 為了數據安全 如果我 ...
  • 前言: 繼上篇:Taurus .Net Core 微服務開源框架:Admin 插件【4-3】 - 配置管理 - Mvc【Plugin-MicroService 微服務】 本篇繼續介紹下一個內容: 系統配置節點:Mvc - Plugin - CORS 跨域界面: 界面如下: 跨域功能相關配置說明如下: ...
  • 前言 由於業務需要,需要多台雲伺服器,但是公有雲的帶寬價格不菲,所以不可能給所有的雲伺服器都配上公網IP,一方面是成本的問題,另一方面也是公網安全的問題。 所以通過其它的方式使用無公網的雲伺服器來來實現對外資源的訪問。 一、操作步驟 至少需要有一臺具有公網IP的雲伺服器! 1、開啟ECS的路由轉發功 ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 眾所周知,vue路由模式常見的有 history 和 hash 模式,但其實還有一種方式-abstract模式(瞭解一哈~) 別急,本文我們將重點逐步瞭解: 路由 + 幾種路由模式 + 使用場景 + 思考 + freestyle 路由概念 ...
  • 架構目標 高可用性 整體系統可用性最低99.9%,目標99.99%。全年故障時間整個系統不超過500分鐘,單個系統故障不超過50分鐘。 高可擴展性 系統架構簡單清晰,應用系統間耦合低,容易水平擴展,業務功能增改方便快捷。 低成本 增加服務的重用性,提高開發效率,降低人力成本; 最終一致性 服務設計能 ...
  • 本文介紹Util應用框架如何記錄日誌. 日誌記錄共分4篇,本文是正文,後續還有3篇分別介紹寫入不同日誌接收器的安裝和配置方法. 概述 日誌記錄對於瞭解系統執行情況非常重要. Asp.Net Core 抽象了日誌基礎架構,支持使用日誌提供程式進行擴展,提供控制台日誌等簡單實現. Serilog 是 . ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...