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

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

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

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

Q&A

解決済

2回答

2638閲覧

C言語 二次元配列を宣言し、この配列の各行の要素数を改行区切りで出力する

whitehorse85921

総合スコア34

C

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

0グッド

0クリップ

投稿2021/05/17 10:23

前提・実現したいこと

いつもありがとうございます。
paizaの「レベルアップ問題集」(これはスキルチェックとは違ってコードを公開できます。)で2次元配列の各行の要素数を改行区切りで出力したいです。

https://paiza.jp/works/mondai/array_primer/array_primer__2dmatrix_output_step5

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

エラーはないのですが、要素数を変えても毎回同じ出力結果「1 2 3」になってしまいます。

該当のソースコード

C

1#include <stdio.h> 2 3int main(void) 4{ 5 int arr[3][3] = {{1, 2}, {3}, {4, 5, 6}}; 6 int cnt = 0; 7 for (int i = 0; i < 3; i++) { 8 for (int j = 0; j < 3; j++) { 9 if (arr[i][j] != 0) { 10 cnt++; 11 printf("%d\n", cnt); 12 break; 13 } 14 } 15 } 16 return 0; 17}

試したこと

for (int i = 0; i < 3; i++) {
printf("%lu\n", sizeof(arr[0]) / sizeof(arr[0][0]));
}
としたのですが出力が
3
3
3
と出力されてしまいます。

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

paiza.ioを使いました。

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

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

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

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

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

guest

回答2

0

ベストアンサー

c

1#include <stdio.h> 2 3int main(void) 4{ 5 int arr[3][3] = {{1}, {2, 3}, {4, 5, 6}}; 6 7 for (int i = 0; i < 3; i++) { 8 int cnt = 0; 9 for (int j = 0; j < 3; j++) { 10 if (arr[i][j] != 0) { 11 cnt++; 12 } 13 } 14 printf("%d\n", cnt); 15 } 16 return 0; 17}

ここでは問題文をもとに配列の要素を変更しています。

投稿2021/05/17 10:32

coolwind0202

総合スコア708

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

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

whitehorse85921

2021/05/17 10:37

coolwind0202様 ありがとうございます! 要素数を変えてもできました! coolwind0202様にもベストアンサーを差し上げたいのですが、先に差し上げた方がいるので差し上げることが出来ず大変に申し訳ありませんm(_ _)m
kaina

2021/05/17 10:48

ベストアンサーは変更することが可能です。 後、ご自分が書いたコードが何故ダメだったのかきちんと理解していますか? 正解のコードを貰って終わりにしてはダメですよ。
whitehorse85921

2021/07/14 10:00

kaina様 気づくのが遅くなり大変申し訳ありません。 ベストアンサーを変更いたしました。 アドバイスありがとうございます。 int cnt = 0;をループの外側に書くと、二重ループで「i < 3;」「j < 3;」で9回カウントすることになってしまうからでしょうか?
kaina

2021/07/20 08:20

やはり理解されていないようですね。 coolwind0202さんの解答とご自身のプログラムの差異をきちんと確認して下さい。 ポイントとしては2重ループの中のif文の中にprintf文を書いているか if文の外に書いているかの違いですよね。 まず、2重ループの中のif文は何を判定しているif文か分かっていますか? それが分かれば何故ダメだったのか分かるはずです。
whitehorse85921

2021/08/20 19:35

kaina様、再びお返事遅れてしまい大変申し訳ありません。 if文の中にprintfを書いてしまうと出力結果が 1 1 2 1 2 3 となってしまいました。 二重ループの中のif文は配列の要素が0以外ならばカウントするということでしょうか? またif文の中にprintfを書いてしまうと、内側のループですべての要素{{1}, {2, 3}, {4, 5, 6}}をカウントしてしまうため、cnt変数が1,12,123となってしまうからでしょうか? お返事が遅れた挙句に何回もすみません。 よろしくお願いいたします。
kaina

2021/08/26 08:00

maisumakunさんが回答されている通り、C言語の2次元配列は全部同じ長さの配列となります。 従って、int arr[3][3] = {{1}, {2, 3}, {4, 5, 6}};というのは int arr[3][3] = {{1, 0, 0}, {2, 3, 0}, {4, 5, 6}};と同義なのです。 ですので、2重ループの中のif文で配列の要素が0以外の場合カウントすることで 配列の各行の入力した要素数が求められるということです。 printfを書く位置について、 1つ目のfor文は2次元配列の行(横)のループで2つ目のfor文は列(縦)のループなので 2重ループの中にprintfを書くと行と列すなわち1つの要素単位でcnt変数を出力することに なります。 問題文には各行の要素数を改行区切りで出力してください。とありますよね? であれば、行単位で処理をする必要があるのは自明の理ですので、 2重ループの中にprintfを書いてはいけないということが分かるはずです。
whitehorse85921

2021/08/28 07:50

kaina様、辛抱強くお付き合いくださり、ありがとうございます。 2重ループの中にprintfを書くと、i が 0 の時、cntが1でcnt 変数のインクリメントしていく過程を一つずつ表示 i が 1 の時、cntが2 で cnt 変数のインクリメントしていく過程を一つずつ表示 i が 2 の時、cntが3 でcnt 変数のインクリメントしていく過程を一つずつ表示 と理解しました。 私の理解不足を補ってくださり、大変にありがとうございました。
guest

0

この問題をC言語で行うことは、厳密に言えば不可能です。

C言語の2次元配列は、全部同じ長さの配列しか作ることが出来ません。

投稿2021/05/17 10:26

maisumakun

総合スコア146018

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

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

maisumakun

2021/05/17 10:27

ポインタの配列などでそれっぽいことを行うことは、できなくはないです。
maisumakun

2021/05/17 10:30

言語によっては配列を配列に入れられるので、それを「二次元配列」として使う例もありますが、C言語では「ポインタの配列」と全く別個な形で「二次元配列」を作れるようになっています。
whitehorse85921

2021/05/17 10:30

maisumakun様 ありがとうございます。「ポインタの配列などでそれっぽいことを行うことは、できなくはないです。」と仰っていたのでぜひ実装してみたいのですが、おすすめのサイトなどございますでしょうか?
maisumakun

2021/07/14 09:53

> ぜひ実装してみたいのですが よほどC言語にコミットしたい事情があるのでない限り、他の言語で書くことをおすすめします。 C言語は、動的なメモリ管理の機能が貧弱で、正しく動作させるだけで苦労が必要です。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問