[英]C: Pointer to struct element inside the struct
為了便於打印,我想創建一個指向我的結構元素的指針數組。 我怎樣才能做到這一點? 我的嘗試是在結構的最后一行。 請注意,此結構具有除 int 之外的其他值,這些值現在顯示在此處。 我只希望對整數進行這種索引。
struct status {
int lastinputVac;
int inputVac;
int outputVac;
/* The unit is % */
int outputpower;
int outputHz;
/* The unit is % */
int batterylevel;
int temperatureC;
int *ordered_values[] = { &lastinputVac, &inputVac, &outputVac, &outputpower, &outputHz, &batterylevel, &temperatureC };
}
硬着頭皮寫額外的代碼,通過結構成員訪問來打印它。 為了節省幾行代碼而犧牲您的設計是不值得的。
想象一下,有一天你必須在庫中公開這個結構。 你真的想用這個沒有實際用途的奇怪指針數組來加載用戶嗎?
所以問題是“我想創建一個指向我的結構元素的指針數組”。 並提到元素可能不是 int。
我寫了一個通用解決方案,在安全性或語言一致性和設計方面可能還需要大量改進,但它顯示了以下問題的一個解決方案。 下面的代碼計算結構的大小,假設結構的元素都是相同的大小,然后構造一個指向元素的指針數組,print_array function 通過打印出這些元素來迭代它們。 我也可以重載 ostream<< 運算符,但我想盡可能保持簡單。
#include "stdafx.h"
struct status {
int lastinputVac;
int inputVac;
int outputVac;
/* The unit is % */
int outputpower;
int outputHz;
/* The unit is % */
int batterylevel;
int temperatureC;
};
//template<typename T>
#include <vector>
#include <algorithm>
#include <iostream>
#include <iterator>
// hide this into a library
template<typename T>
size_t build_array(const status& val, T*** vecptr)
{
const size_t _size = sizeof(status) / sizeof(int);
*vecptr = (T**)malloc( sizeof(T*) *_size );
for (size_t i = 0; i < _size; ++i) {
(*vecptr)[i] = ((T *)((&val)+i));
}
return _size;
}
template<typename T>
void free_array(T** vecptr)
{
free(vecptr);
}
template<typename T>
void print_array(T **vecptr, size_t size)
{
for (size_t i = 0; i < size; i++)
std::cout << *(*vecptr + i) << std::endl;
}
//T1 is the type of the struct and T2 is the type of the elements
template<typename T1, typename T2>
class PrintStruct
{
private:
T2 **m_vecptr;
size_t m_size;
public:
PrintStruct(T1 t) {
m_size = build_array<T2>(t, &m_vecptr);
print_array(m_vecptr, m_size);
}
~PrintStruct() {
free_array(m_vecptr);
}
};
int _tmain(int argc, _TCHAR* argv[])
{
status _status;
_status.batterylevel = 1;
_status.inputVac = 2;
_status.lastinputVac = 3;
_status.outputHz = 4;
_status.outputpower = 5;
_status.outputVac = 6;
_status.temperatureC = 7;
PrintStruct<status, int> _ps(_status);
return 0;
}
這樣是不可能的。
在 C++ 中有一個成員指針(“相對”指針)的概念,這才是你真正需要的。
在你的情況下和 C 我會建議總是使用一個整數數組並且只是命名索引
struct status {
int values[7];
}
..
const int lastinputVac = 0; // or upper case when you like, or use #define
..
status a;
a.values[lastinputVac] = 27;
int z = a.values[lastinputVac];
你明白了嗎?
順便說一句,您可以使用 union 來執行這兩種方法,提供帶有名稱的編譯訪問和通過數組索引的方法
您無法獨立於結構變量實例獲取結構成員的地址; IOW,你必須做類似的事情
struct status foo;
int *ordered_values[] = {&foo.lastInputVac, &foo.inputVac, ...};
但是,鑒於您的所有 struct 成員都是int
s,您可以做一些類型雙關語
int *ordered_values = (int *) &foo;
for (i = 0; i < 7; i++)
printf("%d\n", ordered_values[i]);
這應該有效; struct 實例的地址與其第一個成員的地址相同,並且由於所有成員都是int
s,因此不應該有任何 alignment 或填充問題。 我不推薦這種做法,但就您的目的而言,它應該可以很好地工作。
從閱讀您的評論來看,您似乎對結構有很多元素,但您只想打印其中的一些。 這是我的想法:
1)不要把這個數組放在結構中! 它是 static——它不會因任何struct status
而改變,因此將它放在結構中既浪費又不直觀。
2)您是否考慮過將這些值分離到它們自己的結構中? 然后,您可以使用以下范例:
enum status {
LASTINPUT_VAC,
INPUT_VAC,
OUTPUT_VAC,
OUTPUT_PWR,
OUTPUT_HZ,
BATT_LVL,
TEMPERATURE,
STATUS_MAX
};
struct system {
char name[MAXNAME];
long other_data;
float coords[2];
char *whatever_you_have_here;
int status[STATUS_MAX];
};
然后打印/使用一個你引用它的:
struct system sys;
int temp = sys.status[TEMPERATURE];
for (int i = 0; i < STATUS_MAX; i++)
printf("%d\n", sys.status[i]);
這可能不符合您的確切需求,但我只是想把它放在那里,作為您可以在 C 中執行此類操作的另一種方式。干杯!
我想到了另一種方法。 我的觀察是,成員的順序正確,但您可能希望通過索引輕松訪問。
但警告:你必須關心填充。 填充可能會使整數不對齊。 但是,在 int32 的情況下,我希望沒有問題。
有些人會認為這太老套了,但是,這是有可能的
struct status {
int lastinputVac;
int inputVac;
int outputVac;
/* The unit is % */
int outputpower;
int outputHz;
/* The unit is % */
int batterylevel;
int temperatureC;
} stat;
int* a = &stat;
int maxIndex = (&stat.temperatureC - &stat.lastinputVac) / sizeof (stat); // should be 6
// you could build named constants for that
a[0]; // lastinputVac
a[1]; // inputVac
a[2]; // outputVac
a[3]; // outputpower
a[4]; // outputHz
a[5]; // batterylevel
a[6]; // temperatureC
將結構與數組聯合。 請查閱有關 alignment 的編譯器文檔。
union {
struct {
int someInt0;
int someInt1;
}; //anonymous
int arry[2];
} thing;
~
val0 = thing.someInt0; //structure access
val1 = thing.arry[0]; //gcc, C18, XC8, and XC32 handle this with the top value indexed to 0
if (val0 == val1) {
puts("this works");
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.