#8
by maru » 6年前
構造体の要素をメンバ変数といいます。
構造体のメンバは「構造体変数名.メンバ変数名」、「構造体変数名へのポインタ->メンバ変数名」でアクセスできます。
反復子を使用する場合はポインタと同様です(「構造体コンテナの反復子->メンバ変数名」、「(*構造体コンテナの反復子).メンバ変数名」。)
コード:
struct foo
{
int x; // 構造体メンバx
int y; // 構造体メンバy
int z; // 構造体メンバz
};
int main(int argc, char *argv[])
{
struct foo v[] = {{ 9, 8, 7 },{ 3, 2, 3 }, { -1, -2, -3 } };
const size_t vsize = sizeof(v) / sizeof(foo);
vector<struct foo> vec(vsize);
// 配列添字によるアクセス
for (int i = 0; i < vsize; ++i)
{
vec[i] = v[i]; // vector要素の代入
printf("%d, %d, %d\n", v[i].x, v[i].y, v[i].z);
}
// 配列ポインタによるアクセス
for (struct foo* p = v; p != v + vsize; ++p)
{
printf("%d, %d, %d\n", p->x, p->y, p->z);
}
// vector添字によるアクセス
for (int i = 0; i < vsize; ++i)
{
printf("%d, %d, %d\n", vec[i].x, vec[i].y, vec[i].z);
}
// vectorポインタによるアクセス
for (struct foo* p = &vec[0]; p != &vec[0] + vsize; ++p)
{
printf("%d, %d, %d\n", p->x, p->y, p->z);
}
// vectorイテレータによるアクセス
for (vector<struct foo>::const_iterator i = cbegin(vec); i != cend(vec); ++i)
{
printf("%d, %d, %d\n", i->x, i->y, i->z);
}
return 0;
}
オフトピック
push_back() は要素追加なので当然配列サイズが増える。要素が増えるとき配列の予備領域が不足すると「配列全体を再確保/データのコピー/旧領域の解放」する必要があり、この分のコストが発生する。
配列サイズが小さいうちはこのコストは無視可能であろうが、大きくなると無視できなくなる。
配列サイスが予め分かっているならば、その分のサイズで作成しておき、順次代入する。または reserve()関数により予備領域を確保したうえでpush_back()する。という方法がある。
配列サイスが予め分からなければ、一旦データを数えてから配列を作成したほうが良い場合もある。
順次アクセスしか行わないのであれば、listにする選択肢もある。
コード:
#include <list>
int main(int argc, char *argv[])
{
struct foo v[] = { { 9, 8, 7 },{ 3, 2, 3 },{ -1, -2, -3 } };
list<struct foo> l;
// listへの要素追加
for (int i = 0; i < sizeof(v) / sizeof(foo); ++i)
{
l.push_back(v[i]); // vector要素の代入
}
// イテレータによるアクセス
for (list<struct foo>::const_iterator i = cbegin(l); i != cend(l); ++i)
{
printf("%d, %d, %d\n", i->x, i->y, i->z);
}
return 0;
}
構造体の要素をメンバ変数といいます。
構造体のメンバは「構造体変数名.メンバ変数名」、「構造体変数名へのポインタ->メンバ変数名」でアクセスできます。
反復子を使用する場合はポインタと同様です(「構造体コンテナの反復子->メンバ変数名」、「(*構造体コンテナの反復子).メンバ変数名」。)
[code]
struct foo
{
int x; // 構造体メンバx
int y; // 構造体メンバy
int z; // 構造体メンバz
};
int main(int argc, char *argv[])
{
struct foo v[] = {{ 9, 8, 7 },{ 3, 2, 3 }, { -1, -2, -3 } };
const size_t vsize = sizeof(v) / sizeof(foo);
vector<struct foo> vec(vsize);
// 配列添字によるアクセス
for (int i = 0; i < vsize; ++i)
{
vec[i] = v[i]; // vector要素の代入
printf("%d, %d, %d\n", v[i].x, v[i].y, v[i].z);
}
// 配列ポインタによるアクセス
for (struct foo* p = v; p != v + vsize; ++p)
{
printf("%d, %d, %d\n", p->x, p->y, p->z);
}
// vector添字によるアクセス
for (int i = 0; i < vsize; ++i)
{
printf("%d, %d, %d\n", vec[i].x, vec[i].y, vec[i].z);
}
// vectorポインタによるアクセス
for (struct foo* p = &vec[0]; p != &vec[0] + vsize; ++p)
{
printf("%d, %d, %d\n", p->x, p->y, p->z);
}
// vectorイテレータによるアクセス
for (vector<struct foo>::const_iterator i = cbegin(vec); i != cend(vec); ++i)
{
printf("%d, %d, %d\n", i->x, i->y, i->z);
}
return 0;
}
[/code]
[offtopic]push_back() は要素追加なので当然配列サイズが増える。要素が増えるとき配列の予備領域が不足すると「配列全体を再確保/データのコピー/旧領域の解放」する必要があり、この分のコストが発生する。
配列サイズが小さいうちはこのコストは無視可能であろうが、大きくなると無視できなくなる。
配列サイスが予め分かっているならば、その分のサイズで作成しておき、順次代入する。または reserve()関数により予備領域を確保したうえでpush_back()する。という方法がある。
配列サイスが予め分からなければ、一旦データを数えてから配列を作成したほうが良い場合もある。
順次アクセスしか行わないのであれば、listにする選択肢もある。
[code]
#include <list>
int main(int argc, char *argv[])
{
struct foo v[] = { { 9, 8, 7 },{ 3, 2, 3 },{ -1, -2, -3 } };
list<struct foo> l;
// listへの要素追加
for (int i = 0; i < sizeof(v) / sizeof(foo); ++i)
{
l.push_back(v[i]); // vector要素の代入
}
// イテレータによるアクセス
for (list<struct foo>::const_iterator i = cbegin(l); i != cend(l); ++i)
{
printf("%d, %d, %d\n", i->x, i->y, i->z);
}
return 0;
}[/code][/offtopic]