[解決済み] C言語で2次元配列(行列)を関数に渡すには?
2023-06-26 08:39:04
質問
行列の演算を永続化するためにも必要です。参照渡しが必要ということでしょうか?
これで十分でしょうか?
void operate_on_matrix(char matrix[][20]);
どのように解決するのですか?
C言語には多次元配列はありませんが、それをシミュレートする方法はいくつかあります。そのような配列を関数に渡す方法は、多次元をシミュレートするために使用される方法に依存します。
1) 配列の配列を使用する。これは、コンパイル時に配列の境界が完全に決定されている場合、または、コンパイラが VLA の :
#define ROWS 4
#define COLS 5
void func(int array[ROWS][COLS])
{
int i, j;
for (i=0; i<ROWS; i++)
{
for (j=0; j<COLS; j++)
{
array[i][j] = i*j;
}
}
}
void func_vla(int rows, int cols, int array[rows][cols])
{
int i, j;
for (i=0; i<rows; i++)
{
for (j=0; j<cols; j++)
{
array[i][j] = i*j;
}
}
}
int main()
{
int x[ROWS][COLS];
func(x);
func_vla(ROWS, COLS, x);
}
2) (動的に割り当てられた)配列へのポインタを使用する。これは主に、配列の境界が実行時までわからない場合に使用されます。
void func(int** array, int rows, int cols)
{
int i, j;
for (i=0; i<rows; i++)
{
for (j=0; j<cols; j++)
{
array[i][j] = i*j;
}
}
}
int main()
{
int rows, cols, i;
int **x;
/* obtain values for rows & cols */
/* allocate the array */
x = malloc(rows * sizeof *x);
for (i=0; i<rows; i++)
{
x[i] = malloc(cols * sizeof *x[i]);
}
/* use the array */
func(x, rows, cols);
/* deallocate the array */
for (i=0; i<rows; i++)
{
free(x[i]);
}
free(x);
}
3) 1次元配列を使用し、インデックスを固定化する。これは、静的に割り当てられた(固定サイズ)配列と、動的に割り当てられた配列の両方で使用することができます。
void func(int* array, int rows, int cols)
{
int i, j;
for (i=0; i<rows; i++)
{
for (j=0; j<cols; j++)
{
array[i*cols+j]=i*j;
}
}
}
int main()
{
int rows, cols;
int *x;
/* obtain values for rows & cols */
/* allocate the array */
x = malloc(rows * cols * sizeof *x);
/* use the array */
func(x, rows, cols);
/* deallocate the array */
free(x);
}
4) 動的に割り当てられるVLAを使用する。 オプション2に対するこの利点の1つは、メモリの割り当てが1回で済むことです。もう1つは、ポインタの配列が必要ないため、必要なメモリが少なくて済むことです。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
extern void func_vla(int rows, int cols, int array[rows][cols]);
extern void get_rows_cols(int *rows, int *cols);
extern void dump_array(const char *tag, int rows, int cols, int array[rows][cols]);
void func_vla(int rows, int cols, int array[rows][cols])
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
array[i][j] = (i + 1) * (j + 1);
}
}
}
int main(void)
{
int rows, cols;
get_rows_cols(&rows, &cols);
int (*array)[cols] = malloc(rows * cols * sizeof(array[0][0]));
/* error check omitted */
func_vla(rows, cols, array);
dump_array("After initialization", rows, cols, array);
free(array);
return 0;
}
void dump_array(const char *tag, int rows, int cols, int array[rows][cols])
{
printf("%s (%dx%d):\n", tag, rows, cols);
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
printf("%4d", array[i][j]);
putchar('\n');
}
}
void get_rows_cols(int *rows, int *cols)
{
srand(time(0)); // Only acceptable because it is called once
*rows = 5 + rand() % 10;
*cols = 3 + rand() % 12;
}
(参照
srand()
- はなぜ一度だけ呼び出すのでしょうか?
.)
関連
-
[解決済み] munmap_chunk(): 無効なポインタ
-
[解決済み] char *とchar[]の違い [重複]
-
[解決済み] リストのリストからフラットなリストを作るには?
-
[解決済み] SQLiteのINSERT/per-secondのパフォーマンスを向上させる
-
[解決済み] 変数を参照渡しする方法を教えてください。
-
[解決済み] 1ビットのセット、クリア、トグルはどのように行うのですか?
-
[解決済み] 多次元配列の値によるソート方法
-
[解決済み] JavaScriptで2次元の配列を作成するにはどうすればよいですか?
-
[解決済み] C言語で配列のサイズを決定するにはどうすればよいですか?
-
[解決済み】C言語の関数ポインタはどのように機能するのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
libc++abi.dylib: NSException タイプの捕捉されない例外で終了するエラー
-
VSCodeでCプログラムを書くとエラーになる:ソースファイル "stdio.h" を開くことができない
-
警告:符号付き整数式と符号なし整数式の比較 [-Wsign-compare]
-
[解決済み] MIPSのネストされたForループと配列の使用
-
[解決済み] CコードでEOFを表現する?
-
[解決済み] C言語の**はどういう意味ですか?
-
[解決済み] mallocの結果はキャストするのですか?
-
[解決済み] C言語でランダムなint型を生成するには?
-
[解決済み] printfは、フォーマット文字列の中に改行がないと、呼び出し後にフラッシュしないのはなぜですか?
-
[解決済み] char s[]とchar *sの違いは何ですか?