構造体の要素すべてに対する四則演算の方法を教えてください.
たとえば、
2点a,bの座標成分x,y,zをそれぞれの座標ごとに足す方法を教えてください.
下のようにx,y,z成分を持ったa,bがあります。
struct point{
int x;
int y;
int z;
};
struct point a;
struct point b;
struct point c;

この場合,
c=a+b;
と書くことができず,
それぞれの成分ごとに以下のように足さなくてはなりません.
c.x=a.x+b.x;
c.y=a.y+b.y;
c.z=a.z+b.z;
この方法でできるのですが,
非常に効率的でないのでなにかもっと簡単に記述する方法を教えてください.
お願いいたします.

このQ&Aに関連する最新のQ&A

A 回答 (5件)

久しくCは触ってないのですが、



>c=a+b;
>と書くことができず,
>それぞれの成分ごとに以下のように足さなくてはなりません.
>c.x=a.x+b.x;
>c.y=a.y+b.y;
>c.z=a.z+b.z;

この書き方が正しいです。
構造体の内容が同じInt型ならば、配列で宣言しておいた方が
後の手間は簡単そうです。

この記述をいちいち書くのが面倒ならば、この部分を関数化しておけば、
この処理を呼び出す際の記述は1行で済みます。
(プロの仕事のやり方というのは、そーいうもんです)
    • good
    • 1
この回答へのお礼

お早い回答ありがとうございます.
やっぱり、配列で書いた方がいいですよね。
最近、構造体を使うようになったので、
ちょっと構造体にこだわりたかったです。
でも、おっしゃる通り配列にするのがいちばん簡単なんですよね.

ありがとうございました.

お礼日時:2001/08/17 17:00

2項演算子を再定義しなおせばできます。



struct point operator+(const point& m, const point& n) {
point p;
p.x=m.x+n.x;
p.y=m.y+n.y;
p.z=m.z+n.z;
return p;
}
これで、c=a+bとった具合に「+」で演算できるようになりました。
マイナスも同様です。

struct point operator-(const point& m, const point& n) {
point p;
p.x=m.x-n.x;
p.y=m.y-n.y;
p.z=m.z-n.z;
return p;
}

その他も同様です。
2項演算子の再定義は、「見た目」の可読性をアップさせるための機能であり、
今回のようなケースで、常識的手法として必ずと言って良いほど使用されます。
覚えておくと良いでしょう。
    • good
    • 1

そういう文法はありませんのでできません。


マクロ化や関数化するしかありません。
    • good
    • 1

C言語ですね?



関数で
struct point pointsum(struct point *a, struct point *b)
{
struct point result;
result.x = a->x + b=>x;
result.y = a->y + b=>y;
result.z = a->z + b=>z;

return(result);
}

c = a + b ;がしたいのであれば、
c = pointsum( a, b );

とやるのが一般的ですよ。
でも実は自信がないので(笑)アドバイスということで。
    • good
    • 0
この回答へのお礼

お早い回答ありがとうございます.
今,実際には関数を作ってそれをつかってます。
でも、足す個数が二つになったり,3つになったり,めちゃめちゃたくさんあったりして,実際にはいろんな場合があって関数をすべてに適応させるのが大変なんですよね.
結局配列でやるのが初心者の僕としてはいいかもしれません.

お礼日時:2001/08/17 17:09

言語はCですか?だとしたら、


 void plus(struct point *p1, struct point *p2, struct point *p3)
 {
  p3->x = p1->x + p2->x;
  p3->y = p1->y + p2->y;
  p3->z = p1->z + p2->z;
 }
というような関数を作っておいて
 plus(&a,&b,&c);
としてやるのが普通でしょう。
C++ならもう少しエレガントにできますけどね。
    • good
    • 0
この回答へのお礼

お早い回答ありがとうございます.
今,実際には関数を作ってそれをつかってます。
でも、足す個数が二つになったり,3つになったり,めちゃめちゃたくさんあったりして,実際にはいろんな場合があって関数をすべてに適応させるのが大変なんですよね.
結局配列でやるのが初心者の僕としてはいいかもしれません.

お礼日時:2001/08/17 17:07

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q構造体のマスクというメンバ

一般的な構造体についての質問です。
例えば CHOOSECOLOR 構造体のようにメンバにマスクを持つ構造体があって、
その構造体に値を代入する関数を使うには、CHOOSECOLOR 構造体のマスクを
設定し、そのマスクで有効にしたメンバだけが値を入れられるんですよね?
マスクを持つ構造体というのは、それに値を入れる関数を使う前に
マスクを指定してから、その構造体のアドレスを関数の引数にセット
するんですよね?
マスクは無視されて、それ以外の全てのメンバに値が入るというわけでは
ないですよね?

Aベストアンサー

CHOOSECOLORにマスクは無いと思いますよ。
CHARFORMATですか?CHARFORMATならEM_GETCHARFORMATでbCharSetメンバだけに値を得ることになっているからEM_GETCHARFORMATするときのマスクは参照されません。
その他、SCROLLINFOとか普通のやつはマスクで有効にしたメンバだけがGet*()で得られるメンバです。

Qint main の前のint add(int a,int b) ってなんですか?

int main の前のint add(int a,int b)
ってなんですか?

Aベストアンサー

関数のプロトタイプ宣言です。

賢いコンパイラだと後ろに書いてある実体を見て関数値や引数の型を読み取ってくれたりしますが、コンパイラによっては先に(つまりソースコードのより上の行に)型を宣言しておかないと正しく値の引き渡しができないものもあります。そういったトラブルを避けるために、add()という関数を使う箇所よりも上に、その返り値や引数の型を宣言しておくのです。

ちなみに、#include <stdio.h>というインクルードがありますが、このstdio.hファイルの中には、main()内で利用しているprintf()等の標準関数についてのプロトタイプ宣言なども書かれています。

Q条件によって構造体のリスト構造を変えたい

こんにちは。

C(C++)で構造体を使っているのですが、まだまだ未熟で使い方が良く分かりません。以下のことを実施したいのですが、やり方をどなたかご教授頂けませんでしょうか。よろしくお願いします。

条件によって構造体のリスト構造を変えたいのです。
例えば、
条件1の場合は
構造体a→構造体b

条件2の場合は、
構造体a→構造体c

上記のようにです。そして構造体のルートから参照先をたどっていくことで、配下の構造体の値を取得したいのです。

文法上許されないようですが、イメージとしては、
struct a aa;
aa.c->b.aa

ということをしたいのです。よろしくお願いします。

struct a{
char a;
char b;
struct c;
:
};

struct b{
char aa;
:
};

struct c{
:
:
};

Aベストアンサー

一番手っ取り早いのは、構造体aの中に、構造体bと構造体cの両方のポインタを持たせておいて、使わない側にはNULLを入れるといった方法でしょうか。

struct a
{
 /* .bまたは.cのNULLではない方が有効 */
 struct b *b;
 struct c *c;
};

他には、構造体aと構造体bの最初のフィールドの型を同じにしておいて、そこにaかbかを判別できる値を格納するようにし、構造体aと構造体bの共用体へのポインタを構造体aに持たせるといった方法です。

struct b
{
 char tag; /* 'b'を格納 */
 ...
};

struct c
{
 char tag; /* 'c'を格納 */
 ...
};

struct a
{
 union
 {
  struct b;
  struct c;
 } *p; /* .p->b.tagが'b'なら構造体b, 'c'なら構造体c */
};

好みかもしれませんが、私なら多分前者を使います。

一番手っ取り早いのは、構造体aの中に、構造体bと構造体cの両方のポインタを持たせておいて、使わない側にはNULLを入れるといった方法でしょうか。

struct a
{
 /* .bまたは.cのNULLではない方が有効 */
 struct b *b;
 struct c *c;
};

他には、構造体aと構造体bの最初のフィールドの型を同じにしておいて、そこにaかbかを判別できる値を格納するようにし、構造体aと構造体bの共用体へのポインタを構造体aに持たせるといった方法です。

struct b
{
 char tag; /* 'b'を格納 */
 ...
};
...続きを読む

Qint select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)について

見当違いな質問かもしれませんがお願いします。

複数のソケットを監視する際にselectを使う場合のことですが、
selectの動作と戻り値について疑問があります。

http://www.linux.or.jp/JM/html/LDP_man-pages/man2/select.2.html
ここを参照すると、selectの戻り値は
「更新された 3 つのディスクリプタ集合に含まれているディスクリプタの数 (つまり、 readfds, writefds, exceptfds 中の 1 になっているビットの総数) を返す。」
とあります。
私の中でselectは登録してあるFDのうち、一つでも動きがあれば即座にselectを抜けるもの、という認識です。
この認識だとreadfds,writefdsが引数として与えられているとしても、
どちらかのfd_setのうち、一つでも動きがあればselect文は
抜けてしまうことになります。とすると、戻り値として
「readfds, writefds, exceptfds 中の 1 になっているビットの総数」
は常に1ということになってしまいます。しかし、総数というからには
複数同時に1になることもあるはずです。

私の認識が間違っているとは思うのですが、どう間違っているのかわかりません。
select文の動きについて詳しく教えていただけないでしょうか。
または良いページがあれば教えてください。

見当違いな質問かもしれませんがお願いします。

複数のソケットを監視する際にselectを使う場合のことですが、
selectの動作と戻り値について疑問があります。

http://www.linux.or.jp/JM/html/LDP_man-pages/man2/select.2.html
ここを参照すると、selectの戻り値は
「更新された 3 つのディスクリプタ集合に含まれているディスクリプタの数 (つまり、 readfds, writefds, exceptfds 中の 1 になっているビットの総数) を返す。」
とあります。
私の中でselectは登録してあるFDのうち、一つでも動きが...続きを読む

Aベストアンサー

>私の中でselectは登録してあるFDのうち、一つでも動きがあれば即座にselectを抜けるもの、という認識です。
この認識はあっています。
しかし、selectを呼び出す以前にOKになっているFDがあれば、それらは全てビットがONになります。

話しを簡単にする為に、受信のみのソケットを3つ作成したとします。
これらの3つのソケットに向けて相手が電文を送ったとします。
その状態でまだ、こちらはselectを呼び出さずにいます。しばらくしてから、selectを呼び出すと、selectは即座にリターンし、3つのビットが一度にONになっているはずです。
一方、相手が、一切電文を送ってない状態で、selectを呼び出した場合は、何れかのビットがONになればリターンするので、そのときは、貴方が想像しているように
ビットの総数は1になる可能性が高いです。
従って、相手が電文を送る前にselectを呼び出すか、送った後にselectを呼び出すかは、その時のタイミングにより異なります。従って、ビット数の総和が常に1であるとは、考えない方が無難です。(1つのソケットしか使用しない場合は別ですが・・・)

>私の中でselectは登録してあるFDのうち、一つでも動きがあれば即座にselectを抜けるもの、という認識です。
この認識はあっています。
しかし、selectを呼び出す以前にOKになっているFDがあれば、それらは全てビットがONになります。

話しを簡単にする為に、受信のみのソケットを3つ作成したとします。
これらの3つのソケットに向けて相手が電文を送ったとします。
その状態でまだ、こちらはselectを呼び出さずにいます。しばらくしてから、selectを呼び出すと、selectは即座にリターンし、3つのビ...続きを読む

Q構造体の宣言

下記のように構造体の宣言をした所、

struct B_PARAM test;

「`test' の領域サイズがわかりません」というエラーになってしまいました。この構造体を宣言し、値を入れていこうとしています。

ヘッダファイルに構造体の形は定義してあるのですが、
構造体の中に構造体があるからでしょうか?

またこの構造体を正しく宣言するにはどうすればいいのでしょうか?

Aベストアンサー

typedef struct _B_PARAM {
char p1;
char p2[2];
} B_PARAM;

の、_B_PARAM は、構造体の「タグ名」です。
これは、sutruct とともに使う名前です(C++ struct 無しでもOK)
ですから、この例では、struct _B_PARAM で正解です。

後ろの、B_PARAM は、typedef した名前です。

おおざっぱに言えば、
struct _B_PARAM {
char p1;
char p2[2];
}
という構造体を、B_PARAM という名前で読み替えることを宣言しています。
ですから、こちらを使うのであれば、struct 無しの
B_PARAM test; で正解です。

構造体は必ず typedef しなければならないというものではありません。

Q{x = x>y ? x:y; return x;}

#include <iostream>
using namespace std;

inline int max(int x, int y){x = x>y ? x:y; return x;}

int main()
{
int num1, num2, ans;

cout << "2つの整数を入力して。\n";
cin >> num1 >> num2;

ans = max(num1, num2);

cout << "最大値は" << ans << "です。\n";

return 0;
}
の{x = x>y ? x:y; return x;}の部分の意味が解りません。

Aベストアンサー

inline int max(int x, int y){x = x>y ? x:y; return x;}
これを普通に関数で書くと

int max(int x, int y)
{
x = x>y ? x:y;
return x;
}

です。

x = 部分は右辺の結果が代入されます。これはわかりますよね。
x>y?x:y;
と書くと?より左にある条件式を判定し、その結果が真である場合は:で区切られた左側の値を、偽である場合は右の値を帰します。
x>yが真であればxを、偽であればyを返します。
それが、左辺値xに代入され、関数の戻り値として帰ります。

従って、2つの値をこの関数に入れると、大きいほうの値が帰ることになります。

Q構造体→文字列→構造体 をする方法

VB6.0の話です。

 不特定の構造体を文字列(String)に格納し、これを最初の構造体に戻す事はできませんか?

 具体的には「共有メモリを使い構造体を文字列にして格納>別ウインドウで文字列を取得して構造体に戻す」と言う事をやりたいんです。
 共有メモリに不特定の構造体をいれる方法でもいいんですが…VALIANTだとサイズが大きすぎて実用性がありませんし、違う主旨の質問をするのも良くないので回答はあくまで「構造体→文字列→構造体 をする方法」と言う事でお願いします。

Aベストアンサー

APIを使えば出来ます。

Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (cStr1 As Any, cStr2 As Any, ByVal iLen As Long)


構造体→文字列
Call CopyMemory(strB, ByVal typeA, Len(typeA))

文字列→構造体
Call CopyMemory(typeA, ByVal strB, Len(typeA))

ただし構造体のメンバに配列があると使えません(VBの配列はメモリを連続してとらない為、メモリーリークします)。

また構造体の中身は string *5 などの固定長である必要があります。

以上です。

Q絶対パスがx,y,zのファイル,ホルダを

c:\p.exeにドラッグしてc:\p.exeを実行したとき
[GetCommandLine()]
はどのようになるのでしょうか?
98se 95 Borland C++5.5 Comlierでは
["c:\p.exe" x y z]
になるのですが
Windows2000 + SP3, VC++ 6.0では
["c:\p.exe" "x" "y" "z"]
となるそうです
Me,Xp,NT,2000でBorland c++5.5 Compiler
ではどうのようになるのでしょうか?

Aベストアンサー

前回の質問の続きとして回答します。
(http://www.okweb.ne.jp/kotaeru.php3?q=543088)

次のようなプログラムにすれば、OSのバージョンに依存しないかと思いますがどうでしょうか?

---------------------------------------------------------
#include <windows.h>
#include <string>

int WINAPI WinMain(HINSTANCE , HINSTANCE, LPSTR, int) {
  
  char param[256], buf[256];
  char *p, *b;
  
  /*パラメータ取得とバッファ初期化*/
  strncpy(param, GetCommandLine() , sizeof(param));
  param[255] = '\0';
  memset(buf, 0, sizeof(buf));
  
  /*引用符の除去*/
  p = param, b = buf;
  while(*p != '\0') {
    if (*p != '\"') {
      *b++ = *p++;
    }
    else {
      p++;
    }
  }
  
  /*ファイル名の区切りを\nにする*/
  for(b = buf + 2; *b != '\0'; b++) {
    if ((*b == ':') && (*(b - 2) == ' ')) {
      *(b-2) = '\n';
    }
  }
  
  /*結果確認*/
  MessageBox(NULL, buf, "File Name", MB_OK);
  return 0;
}

前回の質問の続きとして回答します。
(http://www.okweb.ne.jp/kotaeru.php3?q=543088)

次のようなプログラムにすれば、OSのバージョンに依存しないかと思いますがどうでしょうか?

---------------------------------------------------------
#include <windows.h>
#include <string>

int WINAPI WinMain(HINSTANCE , HINSTANCE, LPSTR, int) {
  
  char param[256], buf[256];
  char *p, *b;
  
  /*パラメータ取得とバッファ初期化*/
  strncpy(param, GetCommandLine() ,...続きを読む

QPGにおいて構造体や列挙型はいつ使いますか?

PGにおいて構造体や列挙型はいつ使いますか?

構造体でテーブルみたいなものに一旦入れて、個別に取り出すときに使うと思うのですが、
DBを使ってたら、構造体を使う場所がよくわかりません。

どういうプログラミング時に構造体・列挙型を使うのか教えてください。

Aベストアンサー

複数の項目を一元管理したいとか、あとで(他人が)見た時に判り易いためとか、使う理由は様々あると思います。

例えば、RPG(ゲーム)のプログラミングで、
キャラクターのパラメーターとしてはHP、MP、ちから、すばやさ、EXP等々ありますね。

これを1つの構造体として定義しておく。

主人公 AS 構造体
仲間1 AS 構造体

のようにすれば、1人1人の各パラメータを宣言する手間が省けますし、
何より見やすいですね。
呼び出すときも、主人公.HP、仲間1.HP となってれば、判り易いです。

Q”int *a,*b”というポインタ変数宣言した値でa=&bということ

”int *a,*b”というポインタ変数宣言した値でa=&bということはできる?


”int *a,*b”このような変数をグローバル宣言した場合、
a=&bというようなことはできるのでしょうか?


”int *a,*b”
この宣言で、
aが10番地
bが20番地に定義されたと仮定しています。

Aベストアンサー

#6です。
>回答頂きありがとうございます。
>一応整理させてください。
>質問1:
>(1)int *a, *b; //宣言
>(2)a = b;
>これをメモリアドレスの変化で見ていった場合、
>(1)
>アドレス10:a NULL
>アドレス20:b (仮に1200)
>(2)
>アドレス10:a (仮に1200)
>アドレス20:b (仮に1200)
回答:
OKです。但し
アドレス10:a NULL のところは正確には、アドレス10:a 不定
となります。
不定の意味は初期化していないので何が入っているか判らない。
(0かも知れないし、そうでないかも知れない。あるいは35かも知れないし、そうでないかもしれない)
という意味です。(NULLの箇所は以降同じです)


>質問2:
>(1)' int *a, *b; //宣言
>(2)' a = (int *)&b;
>これをメモリアドレスの変化で見ていった場合
>(1)'
>アドレス10:a NULL
>アドレス20:b NULL
>(2)'
>アドレス10:a 20
>アドレス20:b NULL
>このような違いがあるということですね。
回答
はい、その通りです。

>質問3:
>int *a, *b; //宣言
>a=&b;
>このやり方はできないので、
>もし、やりたいのならば、
>(1)'' int **a, *b //宣言
>(2)'' a=&b;
>これをメモリアドレスの変化で見ていった場合
>(1)''
>アドレス10:a NULL
>アドレス20:b NULL
>(2)''
>アドレス10:a 20
>アドレス20:b NULL
>このようにメモリ内が変化していくということなんでしょうか?
回答
はい、その通りです。
>質問3のポインタのポインタの使い方はこれでよいでしょうか?
回答
はい、よいです。
ちなみに、このような事例に遭遇することはないでしょうが、
int ***a,**b;
の場合、a=&bは構文的に正しいです。
a=(int***)b;(強引なキャスト)
も正しいです。
int *a;
int **a;
int ***a;
の違いを理解することが必要です。
使いませんが、
int **********a;なども構文的にはありです。

#6です。
>回答頂きありがとうございます。
>一応整理させてください。
>質問1:
>(1)int *a, *b; //宣言
>(2)a = b;
>これをメモリアドレスの変化で見ていった場合、
>(1)
>アドレス10:a NULL
>アドレス20:b (仮に1200)
>(2)
>アドレス10:a (仮に1200)
>アドレス20:b (仮に1200)
回答:
OKです。但し
アドレス10:a NULL のところは正確には、アドレス10:a 不定
となります。
不定の意味は初期化していないので何が入っているか判らない。
(0かも知れないし、そうでないかも知れない。あるいは35かも知れない...続きを読む


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング