1. 程式人生 > >VC結構體實現類似陣列的下標操作符功能

VC結構體實現類似陣列的下標操作符功能

在某些特殊時候,我們會想如果結構體也能向陣列一樣通過下標操作符進行操作的話,程式碼將直接通過迴圈語句就能實現,尤其當我們的資料來源於資料庫獲得的資料集時,這種用法還是比較有意思的。

結構體的下標操作這裡只做技術上研究,實際開發中非常不提倡這麼用。原因是這種結構體當成員很多時結構體佔用記憶體將會非常大(結構體SIZE=MAX(成員SIZE)*成員數),而當結構體成員很少時完全沒有必要用下標操作符。這種結構體的下標操作符在實際開發應用中,幾乎是沒有可用價值的。

要實現結構體的下標操作符,我們需要了解,我們所設定的結構體的成員大小必須有規律,那我們直接假設各成員的記憶體大小是相等的,就比較簡單了。怎麼樣才能使結構體的成員記憶體大小都一樣,而且我們還要使結構體支援不同型別的成員?這時就可以想到共同體union了,共同體的好處是各成員共享記憶體。

按這個思路,我們首先將我們需要的類似通過共同體自定義一種新的統一型別:

typedef union __un_MY_VAR
{
	BYTE buf[1024];
	TCHAR cBuf[512];
	int iRs;
	float fRs;
	double dfRs;

	__un_MY_VAR()
	{
		clear();
	}

	void clear()
	{
		memset(buf,0,1024);
	}

} MYVAR;

以上我定義了一個新型別MYVAR,支援字串、整形和浮點型。然後我們就可以用該新型別進行結構體的定義了:
typedef struct __stu_MY_DATA
{
	MYVAR a;
	MYVAR b;
	MYVAR c;
	MYVAR d;
} MYDATA;

以上機構體就是每個成員儲存的記憶體大小相等的。這時候就可以通過過載下標操作符的方法,實現下標操作符功能,思路是通過成員地址偏移來定址成員,新的結構體如下:
typedef struct __stu_MY_DATA
{
	MYVAR a;
	MYVAR b;
	MYVAR c;
	MYVAR d;


	MYVAR operator[](int index) const
	{
		return *(&(this->a) + index);
	}

	MYVAR & operator[](int index)
	{
		return *(&(this->a) + index);
	}

} MYDATA;

這樣一來,假設有一個結構體物件

MYDATA data;

那麼我們就可以直接通過下標來操作結構體成員了,例如data[0],data[1],data[2]的形式。

我編寫了完整的測試程式碼如下:

// testUnionStruct.cpp : 定義控制檯應用程式的入口點。
//

#include "stdafx.h"
#include "windows.h"
#include <iostream>
using namespace std;

#pragma pack(1)

typedef union __un_MY_VAR
{
	BYTE buf[1024];
	TCHAR cBuf[512];
	int iRs;
	float fRs;
	double dfRs;

	__un_MY_VAR()
	{
		clear();
	}

	void clear()
	{
		memset(buf,0,1024);
	}

} MYVAR;

typedef struct __stu_MY_DATA
{
	MYVAR a;
	MYVAR b;
	MYVAR c;
	MYVAR d;


	MYVAR operator[](int index) const
	{
		return *(&(this->a) + index);
	}

	MYVAR & operator[](int index)
	{
		return *(&(this->a) + index);
	}

} MYDATA;

#pragma pack()

#ifdef _UNICODE
#define tcout std::wcout
#define tstrlen wcslen
#else
#define tcout std::cout
#define tstrlen strlen
#endif

int _tmain(int argc, _TCHAR* argv[])
{
	MYVAR myArray[4];
	myArray[0].fRs = (float)1.23;
	myArray[1].dfRs = (double)2.56789;
	myArray[2].iRs = (int)3;
	memcpy(myArray[3].cBuf,_T("A測試B"),7);

	MYDATA data;
	for (int i=0;i<4;i++)
	{
		data[i] = myArray[i];
	}

#ifdef _UNICODE
	locale::global(locale(""));
	wcout.imbue(locale(""));
#endif

	tcout<<data[0].fRs<<std::endl;
	tcout<<data[1].dfRs<<std::endl;
	tcout<<data[2].iRs<<std::endl;
	tcout.write(data[3].cBuf,tstrlen(data[3].cBuf));
	tcout<<std::endl;

	return 0;
}

以上程式碼執行結果:



相關推薦

VC結構實現類似陣列操作符功能

在某些特殊時候,我們會想如果結構體也能向陣列一樣通過下標操作符進行操作的話,程式碼將直接通過迴圈語句就能實現,尤其當我們的資料來源於資料庫獲得的資料集時,這種用法還是比較有意思的。 結構體的下標操作這裡只做技術上研究,實際開發中非常不提倡這麼用。原因是這種結構體當成員很多時

過載陣列操作符,使用operator

原貼:http://blog.csdn.net/keeplooking2510/article/details/8042057     陣列在類的定義中確定好了長度之後,就會限制所要儲存的元素的個數,假如我們要儲存的元素的個數超過了已確定的陣列的長度,那麼就會導致陣列越界。

用C++結構實現順序表的諸多功能

hnu type 結構體 clu 刪除 ace break 輸入數據 環境 編譯運行環境為visual studio 2017 for community #include <iostream> #include<stdlib.h> #defi

用C語言分配動態二維陣列(結構實現)

#include<stdio.h> #include<stdlib.h> typedef struct { double **mat; int m; int n; }Matrix; void InitialMatrix(Matrix *T,in

Leetcode LRU快取,陣列+結構實現

一、演算法思路 LRUCache類有以下函式和變數: LRUCache(int capacity): capacity是當前物件能夠儲存的鍵值對(key,value)最大個數。 int get(int key): 根據指定的key尋找value值,若沒有找到key就返回-1 void put(int key

結構實現棧出現段錯誤

weibo mmd dto MQ TP com 段錯誤 結構體 http b7rd1fvs3p匚緣廖韻陀甘緣吹醬料《http://weibo.com/p/230927987517309797011456》 gxtglkxvpk對蛻穆釁叵墳億斯拾慕《http://weibo

array_map 等php回撥函式使用問題(關聯陣列獲取)

前言:我自己用此類回撥函式,來替代 foreach 純粹是用為程式碼的簡潔性,讓程式碼更好看。(我有點程式碼小潔癖~) 1、array_reduce 當迭代處理一個一維索引陣列時,在回撥函式內是無法獲取到當時元素索引的。所以想要獲取時,需得藉助一個外部變數。 目的:把 $arr 遍歷到 <sele

陣列的由來和為什麼陣列從0開始?

本文索引: 1.陣列的由來: a.字面引申: b.通俗解釋: 陣列的特點: 2.陣列下標為什麼從0開始: a.初步理解: b.加深理解: 1.陣列的由來: // 變數

C++:對結構中字元陣列賦值時,出現表示式必須是可修改的左值的問題

問題描述:         在C++中為結構體中的字元陣列賦值時,出現”表示式必須是可修改的左值“的錯誤提醒,編譯報錯“不可指定資料型別”。           &n

陣列為什麼是從0開始的,而不是1?

依稀記得大一開始學習C語言的時候,對於陣列下標從0開始這一點是非常彆扭難以適應的,感覺這就是反人類的設計。直到今天才瞭解這背後為什麼這樣設計的原理。 為了解釋清楚這個原因,我們來認識陣列的相關特性,據此來探索它底層的一些東西。 隨機訪問 為什麼陣列能支援隨機訪問呢,我們先來看看陣列專業定義。陣列( Arr

結構指標和陣列的使用

同種型別的結構體是可以進行賦值的 【1】結構體陣列 (1)結構體陣列的定義 1)具有相同結構體型別的結構體變數也可以組成陣列,稱它們為結構體陣列。 結構體陣列的每一個數組元素都是結構體型別的資料,它們都分別包括各個成員(分量)項。 2)定義結構體陣列的方法和定義結構體變數的方法相仿

python迴圈陣列

http://outofmemory.cn/code-snippet/3741/accessing-the-index-in-python-for-loops 但是有時候我們會需要在便利陣列的同時訪問下標,這時候可以藉助於enumerate函式來實現,例如: l = [1,2,3]for

c學習筆記--5 結構實現動態連結串列

這裡不得不多說一句,對於c來說指標我認為最好用的就是連結串列,有很多實用的地方 #include<string.h> #include<stdio.h> //C語言 連結串列篇 //結構體實現單向連結串列 struct MyStruc

資料結構---棧和佇列(結構實現

棧(LIFO) 棧(stack)是一種只能在一端進行插入或刪除操作的線性表。 棧頂(top):允許進行插入、刪除操作的一端 棧底(bottom):另一端稱為棧底 進棧或入棧(push):插入操作 出棧或退棧(pop):棧的刪除操作 n個不同元素通過一個棧產生的出棧

(C++)用陣列形式對一維陣列進行排序

用另一個數組下標的形式記錄一個一維陣列中下標所對應的元素出現在個數,並對此一維陣列進行排序。 例如:一個一維陣列中的元素為:a[4] = { 2,3,2,5 };此陣列為一個長度為4的陣列,另一個空陣列x[6]={ 0 };x[0] = 0,因為使用下標的形式記錄a陣列中的元素,此時x[]的

陣列越界的避免方法

為什麼會出現陣列下標越界? C語言不檢查陣列下標的合法性 陣列下標越界的危害 陣列下標越界時,結果隨機。可能導致程式功能不正常,也可能導致程式崩潰。 如何防止陣列下標越界? 1、在使用迴圈遍歷陣列元素時,注意防範off-by-one的錯誤。 2、對於作為函式引數傳入的陣列下標

(pyhon)給定一個整數陣列 nums 和一個目標值 target,請你在該陣列中找出和為目標值的那 兩個 整數,並返回他們的陣列

方法一:使用最容易理解的遍歷陣列進行查詢 def solution(nums,target): #如果列表長度小於2,則直接結束 if len(nums) < 2: return #兩次迴圈列表,分別對列表中的所有可能的數字進行相加

[work] shell中陣列訪問

shell中陣列的下標預設是從0開始的 1。將字串放在陣列中,獲取其長度 #!/bin/bash str="a b --n d" array=($str) length=${#array[@]} echo $length for ((i=0; i<$length;

利用陣列,將n以內的數進行排序

巧用陣列下標 陣列的下標是一個隱含的很有用的陣列,特別是在統計一些數字,或者判斷一些整型數是否出現過的時候。例如,給你一串字母,讓你判斷這些字母出現的次數時,我們就可以把這些字母作為下標,在遍歷的時候,如果字母a遍歷到,則arr[a]就可以加1了,即  arr[a]++;

結構實現成績排序

題目要求 建立一個結構體,讀入並儲存 n 個學生的考試資訊,每個學生的資訊包括學號,姓名和考試分數。然後對學生的分數進行排序(由高到低),若分數相同則按學號排序(由小到大)。最後按照“學號 姓名 成績”的格式逐行列印成績表。 Sample Input 4 1 a 90 2 b