🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

多次元配列

1次元配列内にさらに配列を格納している配列を、多次元配列と呼びます。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

3回答

3238閲覧

C言語によるmallocを用いた二次元配列の作成

kktta

総合スコア1

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

多次元配列

1次元配列内にさらに配列を格納している配列を、多次元配列と呼びます。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2020/12/01 08:48

編集2020/12/01 08:58

前提・実現したいこと

C言語でmallocを使った動的二次元配列を作成したい。
最終的には三桁×三桁の行列を表現するつもり。
配列の中身はdouble型で作成したいです。

発生している問題・エラーメッセージ

配列の中身が0になる

該当のソースコード

#include<stdio.h> #include<stdlib.h> int main(){ int **A; int i,j; A=(int **)malloc(sizeof(int*)*10); for(i=0;i<10;i++){ A[i]=(int *)malloc(sizeof(double)*10); } for(i=0;i<10;i++){ for(j=0;j<10;j++){ A[i][j]=5; } } for(i=0;i<10;i++){ for(j=0;j<10;j++){ printf("%lf\t",A[i][j]); } printf("\n"); } free(A); return 0; }

試したこと

動的二次元配列をいろいろな書きかたで試してみましたがどのパターンでも中身が正しく入れられていない

補足情報(FW/ツールのバージョンなど)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fana

2020/12/01 08:54

int なのか double なのか?
guest

回答3

0

ポインタのサイズが 4 でも 8 でもよくて、free が簡単な方法。

C

1#include <stdio.h> 2#include <stdlib.h> 3 4double **alloc2d(int r, int c) 5{ 6 int r2 = r + (r&1 && sizeof(double*)==4); 7 double **p = malloc(sizeof(double *) * r2 + sizeof(double) * r * c); 8 if (p) { 9 p[0] = (double *)(p + r2); 10 for (int i = 1; i < r; i++) p[i] = p[i-1] + c; 11 } 12 return p; 13} 14 15int main(void) 16{ 17 double **A = alloc2d(3, 3); 18 if (!A) return 1; 19 for (int i = 0; i < 3; i++) 20 for (int j = 0; j < 3; j++) 21 A[i][j] = (i+1) + (j+1)/100.0; 22 for (int i = 0; i < 3; i++) { 23 for (int j = 0; j < 3; j++) 24 printf("%6.2f", A[i][j]); 25 putchar('\n'); 26 } 27 free(A); 28}

投稿2020/12/01 09:51

kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

配列の中身はdouble型で作成したいです。

のであれば、Aの型はdouble **で、A[n]の型はdouble *にしないと。

あとは、

  • (freeするつもりがあるなら) Aをfreeする前に、それぞれのA[n]をfreeする。
  • printfでdoubleを出力するときには%fを使う(C99以降では%lfでもいい)。
  • 好みによるけど、カウンターにしか使わないijはスコープを狭くしたほうがいい。

C

1#include <stdio.h> 2#include <stdlib.h> 3 4int main() 5{ 6 double **A; 7 8 A = (double **)malloc(sizeof(double *) * 10); 9 10 for (int i = 0; i < 10; i++) { 11 A[i] = (int *)malloc(sizeof(double) * 10); 12 } 13 14 for (int i = 0; i < 10; i++) { 15 for (int j = 0; j < 10; j++) { 16 A[i][j] = 5.0; 17 } 18 } 19 20 for (int i = 0; i < 10; i++) { 21 for (int j = 0; j < 10; j++) { 22 printf("%f\t", A[i][j]); 23 } 24 printf("\n"); 25 } 26 27 for (int i = 0; i < 10; i++) { 28 free(A[i]); 29 } 30 free(A); 31 32 return 0; 33}

投稿2020/12/01 09:25

編集2020/12/01 09:25
Daregada

総合スコア11990

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

配列の中身はdouble型で作成したいです。

であれば,あえてintという記述を入れ込む必要はなかろうと思います.
素直にdoubleと書けばよいでしょう.

C

1double **A; 2 3A=(double **)malloc(sizeof(double*)*10); 4for(i=0;i<10;i++){ 5 A[i]=(double *)malloc(sizeof(double)*10); 6}

#なお,解放側(free)の処理が不足しています.mallocしたやつを全てfreeしてください.

投稿2020/12/01 09:18

fana

総合スコア11985

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kktta

2020/12/01 09:27

回答ありがとうございます。返信内容のコードにしたら正常に動きました。 すべてdoubleで書くとポインタの部分もdoubleになりメモリの無駄遣いかと思いポインタ部分はint でしてました。 質問なのですが、ポインタ部分はintで配列の中身はdoubleにすることはそもそもできないのでしょうか?まと外れな質問をしていたらすみません。
fana

2020/12/01 09:34

ポインタのサイズは, int* でも double* でも変わらないでしょう. (何なら,sizeof(int*) とか sizeof(double*) の値を確認してみればわかります) 実体と異なるポインタ型でアドレスを指し示すこと自体はできますが,使う時に相応の対応が必要です. ポインタの演算は型のサイズ次第となるので,intとdoubleのサイズが異なる場合,対処しないと A[i][j] みたいなのが変な領域を指すことになってしまいます.
kktta

2020/12/01 09:39

なるほど、いろいろ勘違いしてました。丁寧にありがとうございます。
fana

2020/12/01 09:42

異なる型のポインタでいじくる話は,例えば, int I[2] = { 0,0 }; //intの配列I unsigned char *pUC = (unsigned char*)I; //Iの場所を強引にunsigned char* で指し示す pUC[1] = pUC[7] = 1; //こんなことしたら一体どうなってしまうのか!? printf( "%d, %d\n", I[0], I[1] ); //(※結果確認用) とか適当に実験してみてもよいかもしれませんね.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問