引数が配列の場合の処理

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
チルチル

引数が配列の場合の処理

#1

投稿記事 by チルチル » 16年前

void data(int data[2]){



}

のような関数に引数を渡したいんですが

色々試した結果

int a[2]={1,2};

data(a);

もしくは

data(0);

という方法でしかコンパイルを通りませんでした

0の場合は数値が必要ない場合だから問題ないんですが

数値が必要な場合は2行にすると見栄えが悪いので

関数の()の中で値を渡す方法はないでしょうか?

box

Re:引数が配列の場合の処理

#2

投稿記事 by box » 16年前

> void data(int data[2]){
> のような関数に引数を渡したいんですが

data[/url]という配列全体を渡したい(はずな)のに、

> data(0);

こんな風に即値だけを渡すのは、したいこととしていることとがマッチしていない、
ということですね。
渡した値ゼロをNULLポインタとみなし、コンパイルは通るかもしれませんが、
実行時にどうなるかは…。

> data(a);
> 関数の()の中で値を渡す方法はないでしょうか?

この方法は、「配列の先頭要素のアドレス」という「値」を
渡している、正しい方法です。
配列の要素数も渡す方がよいとは思いますけれど…。

たかぎ

Re:引数が配列の場合の処理

#3

投稿記事 by たかぎ » 16年前

次のようにします。
data((int[2]){ 1, 2 });
ただし、最新の規格に対応していないコンパイラでは、この方法は使えない可能性があります。

チルチル

Re:引数が配列の場合の処理

#4

投稿記事 by チルチル » 16年前

残念、使えませんでした・・

ちなみにdata関数は例えばの場合で

実際は弾を登録する関数の沢山ある引数の最後に加える予定の引数です

弾の構造体の使わない時が多い配列に代入する値を渡します

なので使わない時は0でOKです

まあ配列だから全部0になるんじゃないかな~

と思ったらフリーズしました・・

使わなければ問題無いとは思いますが・・

box

Re:引数が配列の場合の処理

#5

投稿記事 by box » 16年前

> と思ったらフリーズしました・・

何をしたときにフリーズしましたか?
実行時ですか?

ある関数の引数を配列として、その関数を呼び出しただけで
フリーズするとはちょっと考えにくいです。

もしかすると別の所に原因があるかもしれません。
そこで、関係しそうな箇所のソースを公開するお気持ちはありますか?

チルチル

Re:引数が配列の場合の処理

#6

投稿記事 by チルチル » 16年前

あ~すいません説明不足でした
#include "DxLib.h"

int a;

void data(int data[2]){

	a=data[0];

}

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
ChangeWindowMode(TRUE);SetOutApplicationLogValidFlag( FALSE );
if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;//初期化と裏画面化

data(0);

DxLib_End();
return 0;

}
引数になっている変数を呼び出すだけなら動くんですが
その変数で代入とか比較とかをやるとフリーズするようですね

これだと条件分岐ができませんからやっぱり無理ですね・・
引数の初期化とかも無理でしたし・・

でも引数がNULLにできる関数は沢山ありますよね
一体どうなっているんでしょうか・・

KEYONN_

Re:引数が配列の場合の処理

#7

投稿記事 by KEYONN_ » 16年前

2次元配列が引数の関数に値を渡す時は、
int Tbl[300][20]={0};

int ArrayProc(Tbl[/url][20])
{
    //処理
    return 0;
}
でいけます。

MNS

Re:引数が配列の場合の処理

#8

投稿記事 by MNS » 16年前

引数に0を渡したということは、
NULLポインタを渡したこととなりますから、
data[0]が指す先のアドレスはNULLになります。
ですので、data[0]へアクセスしようとすると
フリーズするのは、別におかしくはないはずです。

チルチル

Re:引数が配列の場合の処理

#9

投稿記事 by チルチル » 16年前

う~ん、これは困りましたね・・
やはり関数の中だけで処理するのは無理なんでしょうか・・

box

Re:引数が配列の場合の処理

#10

投稿記事 by box » 16年前

今一度、当該の関数に何を渡して、当該の関数の中で何をしたいかを
整理してみたらいかがでしょうか。

単にint型1個だけを渡して処理したいのであれば、
わざわざ配列(へのポインタ)を渡す必要はないです。

チルチル

Re:引数が配列の場合の処理

#11

投稿記事 by チルチル » 16年前

やりたい事をまとめると

①沢山ある引数の最後の引数に配列を渡す

②構造体の配列に代入

③配列だと後から数を変えやすそう?

④使わない時はできるだけ短くしたい
理想は隠し引数のように何も書かなくて良い

kazuoni

Re:引数が配列の場合の処理

#12

投稿記事 by kazuoni » 16年前

1~4のつながりがよく分かりません。。

1.は配列の先頭のポインタとサイズを渡せばこの質問の事は済みます。
 boxさんのおっしゃるとおり、1個の要素なら必要ないですが・・・

2.は構造体の配列に何を代入するのですか?
 1.で渡した配列は構造体の配列で、要素をごっそりすべてコピーするということですか?

3.は確かに、配列ならはa[100]→a[1000]とすれば要素数は変えられます。
 引数にするならば、aをint型の配列とすると、引数に(a,sizeof(a)/sizeof(a[0]))を加えれば、
 要素数を変えても、うまいこと配列にアクセスできます。

4.「何を」使わない時は「何を」できるだけ短くしたいのですか?
 隠し引数=可変個引数ということですか?それとも、省略実引数ですか?

チルチル

Re:引数が配列の場合の処理

#13

投稿記事 by チルチル » 16年前

すいません①~④は特に繋がってるわけではありません・・

①は引数の最後を配列にして複数の数値を渡せるように
あと、ならべく少ない手順で渡したい・・

②は弾の構造体にも同じ要素数の配列があり、引数の配列の数値を構造体の配列に代入

③は後で要素数が足らなくなった場合に増やしやすいように・・

④弾の構造体の配列は角度とかを記録しておかないと表現できない弾幕を作る時に使うので普段は使いません
なので使わない時まで引数を渡すと見にくくなるので省略したい・・
隠し引数には詳しくないのでよくわかりませんが
描画系関数の反転フラグみたいな感じでしょうか・・

lbfuvab

Re:引数が配列の場合の処理

#14

投稿記事 by lbfuvab » 16年前

デフォルト引数なんかで調べてみてはいかがでしょうか。

チルチル

Re:引数が配列の場合の処理

#15

投稿記事 by チルチル » 16年前

あ~なるほど、こんな機能あったんですね
初期値の設定はできそうなんだけどな~
と思ってましたがプロトタイプ宣言時にするとは思いませんでした
まあ関数の方が上なら必要ないようですが

って事は
void DATA(a,b,c,data[5]=0);
みたいな感じですね
あとは()内で引数を渡す方法ですね

チルチル

Re:引数が配列の場合の処理

#16

投稿記事 by チルチル » 16年前

>>data((int[2]){ 1, 2 });

これはできませんでしたが
こんな感じの方法は他にないでしょうか?

Justy

Re:引数が配列の場合の処理

#17

投稿記事 by Justy » 16年前


>こんな感じの方法は他にないでしょうか

 boostが使えるなら

[color=#d0d0ff" face="monospace]
#include <boost/assign/std/vector.hpp>
#include <boost/assign/list_of.hpp>
#include <vector>

// 対象の配列
int arr[5];

// セット関数
void set_vector_data(const std::vector<int> &v)
{
const std::size_t arr_size = sizeof(arr)/sizeof(arr[0]);
const std::size_t v_size = v.size();
const std::size_t copy_size = arr_size < v_size? arr_size: v_size;
for(std::size_t n=0; n<copy_size; ++n)
arr[n] = v[n];
}

{ // 使うとき・・・お好みで (数字)(数字)...と繋げる
using namespace boost::assign;
set_vector_data(list_of(1));
set_vector_data(list_of(1)(2));
set_vector_data(list_of(1)(2)(3));
set_vector_data(list_of(1)(2)(3)(4));
}
[/color]


 使えないなら、オーバーロードしてみるのも一興。
[color=#d0d0ff" face="monospace]
// セット関数
void set_data_(int n, int val0, int val1 = 0, int val2 = 0, int val3 = 0)
{
if(n >= 1) arr[0] = val0;
if(n >= 2) arr[1] = val1;
if(n >= 3) arr[2] = val2;
if(n >= 4) arr[3] = val3;
}

void set_data(int val0, int val1, int val2, int val3)
{
set_data_(4, val0, val1, val2, val3);
}
void set_data(int val0, int val1, int val2)
{
set_data_(3, val0, val1, val2);
}
void set_data(int val0, int val1)
{
set_data_(2, val0, val1);
}
void set_data(int val)
{
set_data_(1, val);
}

{ // 使うとき
set_data(1);
set_data(1, 2);
set_data(1, 2, 3);
}
[/color]

チルチル

Re:引数が配列の場合の処理

#18

投稿記事 by チルチル » 16年前

何だかすごそうな処理ですね・・
とりあえずboostとかオーバーロードとかを知らないので無理ですね・・
見た感じ値を代入する処理を先に作っているようですが
これだと一行に収まらないのでちょっとまずいですね・・

チルチル

Re:引数が配列の場合の処理

#19

投稿記事 by チルチル » 16年前

原点に戻りますが

dat[0]=0,dat[1]=1,dat[2]=2,dat[3]=3,dat[4]=4;

DATA(a,b,c,data);

が一番短そうなんですが
dat配列の宣言と初期化を()の中でできないでしょうか?

たいちう

Re:引数が配列の場合の処理

#20

投稿記事 by たいちう » 16年前

不自然な方法で短くことに何のメリットも感じませんが、
どうしてもというなら可変長引数について調べてみてはどうでしょうか。

http://www.kumei.ne.jp/c_lang/intro/no_43.htm

C++でクラスの設計の勉強をするのが一番のお勧めです。

たかぎ

Re:引数が配列の場合の処理

#21

投稿記事 by たかぎ » 16年前

> 不自然な方法で短く(書く)ことに何のメリットも感じませんが、

賛成です。
どうしてもやりたければ、最善の方法はC99に対応したコンパイラに変えることであり、次善策は、
int a[2]={1,2}; data(a);
と1行で書くことです。

チルチル

Re:引数が配列の場合の処理

#22

投稿記事 by チルチル » 16年前

C99が何かよくわかりませんが
コンパイラの変更は無理ですね・・

可変長引数は「,」の数が増えるのでダメですね・・

よく考えたら
data((int[2]){ 1, 2 });
だって「,」が増えるから意味無いか・・

ここは配列の要素の数だけ隠し引数を用意しておくのがベストかな・・
要素を全部使わない時まで書かなきゃいけなくなる可能性だってあるし・・
増やすの簡単そうだし・・

閉鎖

“C言語何でも質問掲示板” へ戻る