1次元に直す時の副作用は? – プログラミング – Home

1次元に直す時の副作用は?
 
通知
すべてクリア

[解決済] 1次元に直す時の副作用は?


かい
 かい
(@かい)
ゲスト
結合: 18年前
投稿: 3
Topic starter  

main()の方で、
static int a;
static int b;
static int c;
static int d;
int e;
int KAI[5][6][7][8];

e = Kai[a][b][c][d];

として、使っていたものを、
KAIに対して、
関数の引数(入力)として、
*FKAIとして引渡して、
KAIF[a*6*7*8+b*7*8+c*8+d]
という、1次元の使い方をしようとしています。

これで、関数には、引数は、引き渡ると思うのですが、
こういった場合、関数内で、KAIF[ ]をしようしているうちに、
main()側で、
int KAI[5][6][7][8];
以降で型宣言している変数を、食いつぶす、等の
副作用は、絶対、ありないのでしょうか?


引用未解決
トピックタグ
。
 。
(@。)
ゲスト
結合: 22年前
投稿: 10
 

理解不能です。
自分の文章もう一度読み返してみては。

> int KAI[5][6][7][8];
> e = Kai[a][b][c][d];
KAIとKaiはおなじもの?(C言語は大文字小文字を分ける)

>*FKAIとして引渡して、
>KAIF[a*6*7*8+b*7*8+c*8+d]
>KAIF[ ]をしようしているうちに
FKAIとKAIFはおなじもの?(これにいたっては全く違う)


返信引用
a
 a
(@a)
ゲスト
結合: 23年前
投稿: 59
 

KAIF[a*6*7*8+b*7*8+c*8+d]

n = a*6*7*8+b*7*8+c*8+d;
n が許容範囲か使う前に調べ、その後で
KAIF[n]


返信引用
旧通りすがり
 旧通りすがり
(@旧通りすがり)
ゲスト
結合: 18年前
投稿: 2
 

>int KAI[5][6][7][8];
>以降で型宣言している変数を、食いつぶす、等の
>副作用は、絶対、ありないのでしょうか?
範囲外をアクセスすれば壊せるでしょう


返信引用
かい
 かい
(@かい)
ゲスト
結合: 18年前
投稿: 3
Topic starter  

すいません。
変数名、書き間違いました。
下記です。
今までいただいているご回答だと、
a<5, b<6, c<7, d<8
で使う分には、main()から関数に入って、
KAIの従来の4次元が、KAIFの1次元になったとしても、
壊れることはない。
その範囲を逸脱したら、後の型宣言した変数まで、
食いつぶす、という理解でいいでしょうか?

================================================================

main()の方で、
static int a;
static int b;
static int c;
static int d;
int e;
int KAI[5][6][7][8];

e = KAI[a][b][c][d];

として、使っていたものを、
KAIに対して、
関数の引数(入力)として、
*KAIFとして引渡して、
KAIF[a*6*7*8+b*7*8+c*8+d]
という、1次元の使い方をしようとしています。

これで、関数には、引数は、引き渡ると思うのですが、
こういった場合、関数内で、KAIF[ ]をしようしているうちに、
main()側で、
int KAI[5][6][7][8];
以降で型宣言している変数を、食いつぶす、等の
副作用は、絶対、ありないのでしょうか?


返信引用
超初心者
 超初心者
(@超初心者)
ゲスト
結合: 23年前
投稿: 139
 

> 関数の引数(入力)として、
> *FKAIとして引渡して、
このKAIFが不明瞭
ちゃんと具体的に示さないと良いか悪いか判断は難しいんじゃないの

勝手に想像してみた。
動作確認していないので動くかどうかは知らない。

int func(int * KAIF, int a, int b, int c, int d)
{
return KAIF[a*6*7*8+b*7*8+c*8+d];
}

int main()
{
int KAI[5][6][7][8];
int e = func((int*)&KAI[0][0][0][0],1,2,3,4);
return 0;
}


返信引用
超初心者
 超初心者
(@超初心者)
ゲスト
結合: 23年前
投稿: 139
 

範囲を間違えなければ問題ないよ。
C言語の規格でどうなっているか知らないけどさ。

int main()
{
int a;
int KAI[5][6][7][8];
int b;
仮に範囲を超えたとして
aが壊れるかbが壊れるか私にはわかりません
スタックが壊れてリターンがおかしくなるかもね。


返信引用
かい
 かい
(@かい)
ゲスト
結合: 18年前
投稿: 3
Topic starter  

申し訳ないです。
その記載の通りです。

範囲を超えなければ大丈夫そうですね。

3次元が、関数に入って1次元になるのは、
奇妙だという人がいたので、
(ただ、ずーっと、staticの変数を使うことを通す以外は、そうしか出来ないので)、
当たり前のように、こういう使い方をして来た自分が
おかしいのかな、と思って聞いてみました。


返信引用
2リットル
 2リットル
(@2リットル)
ゲスト
結合: 18年前
投稿: 9
 

解決後にあれですが、

>3次元が、関数に入って1次元になるのは、
>奇妙だという人がいたので

私も奇妙だと感じます。

Cで関数の引数に多次元配列をとる場合は以下のようにできませんでしたっけ?
int func(int array[5][6][7][], int x, int y, int z, int t)

定数をきりたくないとか種々の理由でKAIFを選択されているのなら
呼び出し側もKAIをつかわずにKAIFだけで記述したら?
と思います。


返信引用
PATIO
(@patio)
Famed Member
結合: 3年前
投稿: 2660
 

というか、ポインタには次元数とか配列のサイズに関する情報はついてこないので
元の宣言が何次元だろうが、ポインタで引き渡された段階で単なるメモリの塊なのでは?

コンパイラがコードを生成する時点ではその変数のスコープ内において
次元数とか添え字の最大値はわかっているでしょうけれど、
それはあくまでもコンパイル時の話であって実行されている時点ではないはずだし。

変数自体がこの辺の情報を保持しているような言語ならともかく、
C言語やC++言語では無理だと思います。
C++言語でその辺まで管理したいのであれば、
そういうクラスを自作すれば良いという話になりませんかねぇ。


返信引用
yoh2
 yoh2
(@yoh2)
ゲスト
結合: 18年前
投稿: 70
 

同じく奇妙に感じますが、Cの規格上は、配列は要素と要素の間にも、配列の末尾にもパディングが
入らないことが保証されている(*)ので、単なるint*として扱ってしまう方法も、一応OKです(**)。
(*) 型TがN個からなる配列のサイズはsizeof(T)となるという規則から。
(**) 厳密には、もうひとつ、オブジェクトにアクセスできる条件を満たす必要がありますが、
intの多次元配列型を持つ変数にintでアクセスすることはその条件を満たしています。
(ややこしいので、詳しくはJIS X 3010 6.5 「式」の後半部分を参照して下さい)

しかし、基本的には以下の意見に賛成です。

> 定数をきりたくないとか種々の理由でKAIFを選択されているのなら
> 呼び出し側もKAIをつかわずにKAIFだけで記述したら?
> と思います。

どうしても元の変数を多次元配列にして、関数を一次元配列として扱いたいなら、

func(void *KAIF, int a, int b, int c, int d)

のように、第一引数をvoid*にしてしまえば、呼び出し側で余計なキャストをしなくても、
(多分)警告なしで使えるので、多少なりとも気持ち悪さは軽減できるかと。

ちなみに、引数に多次元配列を渡す場合の書き方についてですが、

> Cで関数の引数に多次元配列をとる場合は以下のようにできませんでしたっけ?
> int func(int array[5][6][7][], int x, int y, int z, int t)

添字を省略できるのは変数名に一番近い方です。int array[5][6][7][8]というのは
(((int 8個からなる配列)が7個からなる配列)が6個からなる配列)が5個からなる配列
であって、関数の引数では、「~がN個からなる配列」が「~へのポインタ」扱いされるわけですか
ら。


返信引用
yoh2
 yoh2
(@yoh2)
ゲスト
結合: 18年前
投稿: 70
 

ミス。

> (*) 型TがN個からなる配列のサイズはsizeof(T)となるという規則から。

正しくは、
型TがN個からなる配列のサイズはsizeof(T)×Nとなるという規則から。
です。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました