質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.35%
C

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

Q&A

解決済

3回答

1022閲覧

Cの2次元配列のポインタを一次配列の初期値で定義したがコンパイルエラーの修正方法がわからない

fukuro

総合スコア3

C

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

0グッド

0クリップ

投稿2021/10/21 06:43

編集2021/10/22 07:11

サイズ(行、列)が同じで初期値を持つ2次元配列複数を定義し、その各々のポインターを1次配列に定義して、引数により選択する2次元配列を切り替えるというCソフトについて、以下のようにコンパイルエラーが発生し修正方法が不明です。

関係箇所のソースを掲載しました。
・(1),(2)のように2次元配列を定義し初期値を設定しています。掲載内容はその一部分です。
・(3)は上記2次元のポインターを1次配列で初期値として定義しました。
ここでエラー内容の「temperature_steam_f.c:8485:2: 」が発生しています。
・(4)は引数により切り替えるために(1)(2)...と同じ配列でポインタを定義しました。
・(5)で2次元配列の今回の行列のポインターを設定しています。
ここでエラー内容の「temperature_steam_f.c:8502:8:」が発生しました。

ポインターについてなかなか理解が難しく、今回のエラーはどう修正していいかわかりません
どなたかご教示頂けると幸いです。

<エラー内容>
temperature_steam_f.c:8485:2: warning: incompatible pointer types initializing 'double (*)[14]' with an expression of type 'double *' [-Wincompatible-pointer-types]
(double *)ytble1,(double *)ytble2,(double *)ytble3,(double *)ytble4,(double *)ytble5,
^~~~~~~~~~~~~~~~
temperature_steam_f.c:8485:19: warning: excess elements in scalar initializer [-Wexcess-initializers]
(double *)ytble1,(double *)ytble2,(double *)ytble3,(double )ytble4,(double )ytble5,
^~~~~~~~~~~~~~~~
temperature_steam_f.c:8502:8: warning: incompatible pointer types assigning to 'double (
)[301][179]' from 'double [14]' [-Wincompatible-pointer-types]
ytble=ytable_p[zp];
<ソース部分>
temperature_steam_f.c:8485:2: warning: incompatible pointer types initializing 'double (
)[14]' with an expression of type 'double *' [-Wincompatible-pointer-types]
(double *)ytble1,(double *)ytble2,(double *)ytble3,(double *)ytble4,(double *)ytble5,
^~~~~~~~~~~~~~~~
temperature_steam_f.c:8485:19: warning: excess elements in scalar initializer [-Wexcess-initializers]
(double *)ytble1,(double *)ytble2,(double *)ytble3,(double *)ytble4,(double )ytble5,
^~~~~~~~~~~~~~~~
temperature_steam_f.c:8502:8: warning: incompatible pointer types assigning to 'double (
)[301][179]' from 'double [14]' [-Wincompatible-pointer-types]
ytble=ytable_p[zp];

<プログラムソース部分(抜粋)>
(途中略)
#define xnum_s 179 // column size of ytble1x
#define tnum_s 4101 // row size of the ytble
#define tnum_z 300 // row size of a ytble1x
#define tnum_b (int)((tnum_s+tnum_z-1)/tnum_z) // number of ytble1x block

(途中略)

(1) double ytble1[tnum_z+1][xnum_s]={

// Z=1 kj/kg
{ 6.97, 17.495, 24.08, 28.962, 32.875, 36.16, 39.001, 41.51, 43.762, 45.808, 49.42, 52.548, 55.31399999999999, 57.799, 60.059, 62.133, 64.054, 65.843, 67.518, 69.095, 70.586, 72.0, 73.345, 74.62899999999999, 75.857, 77.03399999999999, 78.165, 79.25399999999999, 80.303, 81.317, 83.709, 85.926, 87.993, 89.932, 91.758, 93.485, 95.125, 96.68700000000001, 98.178, 99.60600000000001, 102.29, 104.78, 107.11, 109.29, 111.35, 113.3, 115.15, 116.91, 118.6, 120.21, 121.76, 123.25, 124.69, 126.07, 127.41, 128.71, 129.97, 131.19, 132.37, 133.53, 135.74, 137.85, 139.85, 141.77, 143.61, 145.38, 147.08, 148.72, 150.3, 151.84, 155.46, 158.83, 161.99, 164.95, 167.76, 170.41, 172.94, 175.36, 177.67, 179.89, 182.02, 184.07, 186.05, 187.96, 189.82, 191.61, 193.35, 195.05, 196.69, 198.3, 199.86, 201.38, 202.86, 204.31, 205.73, 207.12, 208.48, 209.81, 211.11, 212.38, 214.87, 217.26, 219.56, 221.8, 223.96, 226.05, 228.09, 230.06, 231.99, 233.86, 235.68, 237.46, 239.2, 240.9, 242.56, 244.19, 245.78, 247.33, 248.86, 250.36, 251.83, 253.27, 254.68, 256.07, 257.44, 258.78, 260.1, 261.4, 262.68, 263.94, 266.41, 268.8, 271.12, 273.38, 275.59, 277.73, 279.83, 281.88, 283.88, 285.83, 287.74, 289.62, 291.45, 293.25, 295.01, 296.74, 298.44, 300.1, 301.74, 303.35, 304.93, 306.48, 308.01, 309.52, 311.0, 314.61, 318.08, 321.44, 324.68, 327.82, 330.86, 333.81, 336.67, 339.45, 342.16, 344.79, 347.36, 349.86, 352.29, 354.67, 356.99, 359.26, 361.47, 363.63, 365.75, 367.81, 369.83, 371.8, 373.71},
// Z=2 kj/kg
{ 6.97, 17.495,
(途中略)
79, 347.36, 349.86, 352.29, 354.67, 356.99, 359.26, 361.47, 363.63, 365.75, 367.81, 369.83, 371.8, 373.71}};

(2) double ytble2[tnum_z+1][xnum_s]={

// Z=300 kj/kg
{ 6.97, 17.495, 24.08, 28.962, 32.875, 36.16, 39.001, 41.51, 43.762, 45.808, 49.42, 52.548, 55.31399999999999, 57.799, 60.059, 62.133, 64.054, 65.843, 67.518, 69.095, 70.586, 72.0, 73.345, 74.62899999999999, 75.857, 77.03
(途中略)

(3)/* */

double (*ytable_p)[tnum_b]={
(double *)ytble1,(double *)ytble2,(double *)ytble3,(double *)ytble4,(double *)ytble5,
(double *)ytble6,(double *)ytble7,(double *)ytble8,(double *)ytble9,(double *)ytble10,
(double *)ytble11,(double *)ytble12,(double *)ytble13,(double *)ytble14
};

(4) /* */

double (ytble)[tnum_z+1][xnum_s]; // curent ytble pinter
/
**************************************

  • main

****************************************/
//printf("T = %0.f P=%f xtable[0]=%f \n", T,P,xtable[0]);
Pm[0]=P;
int l,m,mm,ll;
int z1,z2,zp,zbias;
z1 = (int)(fmod(T,tnum_z));
z2 = (int)(fmod((T+0.9999999), tnum_z));
zp = (int)(T/tnum_z);
zbias = zp * tnum_z;

(5)/* */

ytble=ytable_p[zp];

対策1:

丸括弧は不要との助言から以下に訂正しました。
double *ytable_p[tnum_b]={
(double *)ytble1,(double *)ytble2,(double *)ytble3,(double *)ytble4,(double *)ytble5,
(double *)ytble6,(double *)ytble7,(double *)ytble8,(double *)ytble9,(double *)ytble10,
(double *)ytble11,(double *)ytble12,(double *)ytble13,(double *)ytble14
};
double *ytble[tnum_z+1][xnum_s];

結果:エラーが1つになりました。但し、このエラーの改修方法がわかりません。
temperature_steam_f.c:8509:7: error: array type 'double *[301][179]' is not assignable
ytble=ytable_p[zp];

対策2:「2次元配列をパラメータで渡すサンプル」で試した結果

fanaさんからの内容で1次配列でアクセスできるようになったので、jimboさんからの2次元でのアクセスの確認を行いました。
(ロジックの見易さから2次元にしたいので)
jimboさんからの本内容に従って修正して見ました。結果、コンパイルエラーが発生しましたが、一部変更することでエラーはなくなりました。確認はこれからですが状況を下記に記載します。
みなさん、ありがとうございます。
<修正>
double (yp[])[tnum_z+1][xnum_w]={
ytble1,ytble2,ytble3,ytble4,ytble5,
ytble6,ytble7
};
<コンパイルエラー>
temperature_water_f.c:4114:2: warning: incompatible pointer types initializing 'double (
)[301][179]' with an expression of type 'double [301][179]'; take the address with & [-Wincompatible-pointer-types]
<対応>
下記のように&をつけたところエラーがなくなりました。
&ytble1,&ytble2,&ytble3,&ytble4,&ytble5,&ytble6,&ytble7
<結果>
結果はyp[i][j]で値を取得できるようになると思いますが、これから確認です。
ありがとうございます。

対策3:上記2次元での確認を進めていますがエラーが消せません。

サンプルでのロジックも上記&をつけるようエラーが出ました。
&をつけましたが、もう一件エラーがでます。
もし対応方法分かりましたらご教示ください。
<エラー内容>
test2.c:18:11: warning: incompatible pointer types passing 'int ()[2][3]' to parameter of type 'int ()[3]' [-Wincompatible-pointer-types]
print(p[i]);
test2.c:3:16: note: passing argument to parameter 'p' here
void print(int p[2][3]) {
<ソース>
#include <stdio.h>

void print(int p[2][3]) {
for(int i=0; i<2; i++)
for(int j=0; j<3; j++)
printf(" %d", p[i][j]);
printf("\n");
}
int main(void){
int A[2][3] = { {1,2,3}, {4,5,6} };
int B[2][3] = { {11,12,13}, {14,15,16} };
int C[2][3] = { {21,22,23}, {24,25,26} };
int D[2][3] = { {31,32,33}, {34,35,36} };

int (*p[])[2][3] = { &A, &B, &C, &D };

for(int i=3; i>=0; i--)
print(p[i]);
}

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

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

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

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

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

jimbe

2021/10/21 09:15

コード部分がむちゃくちゃになっています。 コードのご提示はマークダウン記法をご利用ください。 マークダウンに付きましてはヘルプを参照してください。
y_waiwai

2021/10/21 10:27

このままではコードが読みづらいので、質問を編集し、<code>ボタンを押し、出てくる’’’の枠の中にコードを貼り付けてください
guest

回答3

0

double (*ytable_p)[tnum_b]は、配列へのポインタという意味になります。

double *の配列を作りたいなら丸括弧は不要で、double *ytable_p[tnum_b]と書いてください。

投稿2021/10/21 06:49

maisumakun

総合スコア146018

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

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

0

ベストアンサー

少し諄い感じですが、 2次元配列をパラメータで渡すサンプルを作ってみました。

c

1#include <stdio.h> 2 3void print(int p[2][3]) { 4 for(int i=0; i<2; i++) 5 for(int j=0; j<3; j++) 6 printf(" %d", p[i][j]); 7 printf("\n"); 8} 9int main(void){ 10 int A[2][3] = { {1,2,3}, {4,5,6} }; 11 int B[2][3] = { {11,12,13}, {14,15,16} }; 12 int C[2][3] = { {21,22,23}, {24,25,26} }; 13 int D[2][3] = { {31,32,33}, {34,35,36} }; 14 15 int (*p[])[2][3] = { A, B, C, D }; 16 17 for(int i=3; i>=0; i--) 18 print(p[i]); 19}

↓こんなのも読まれると良いかもしれません。
ポインタ虎の巻~多次元配列の実現

投稿2021/10/21 11:29

編集2021/10/21 11:33
jimbe

総合スコア13209

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

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

0

たとえば,ある X 型の変数が2つあって,それを選択するとしたら,

X A,B; //2つあって, X *pX[2] = { &A, &B }; //ポインタの配列があって… X *pCurrSelectedX = pX[0]; //こんな感じで選択する

みたいな感じに書けばよいのではないでしょうか?
すなわち,
モノが X 型なのであれば,ポインタの配列は素直に X* の配列にすればよい.

何故,強引に

(double *)ytble1

とかするのか? (何故別の型に無理矢理キャストして保有するのか?)
やるならやるで,それを使う箇所:

ytble=ytable_p[zp];

のところでは,もう一回正しい(元々の)型にキャストしてやる必要がありますよね.

投稿2021/10/21 08:41

fana

総合スコア11996

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問