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

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

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

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

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

Q&A

解決済

2回答

343閲覧

C言語 ポインタを使って自然数のすべての位を1の位の数で置き換えたい

supercubo

総合スコア1

C

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

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

0グッド

0クリップ

投稿2024/02/11 08:42

編集2024/02/11 08:46

イメージ説明
早めの回答をしてくださると助かります...!!
現在、高等専門学校でC言語のポインタの範囲を勉強しています。
上のような問題を解いています。プログラムの添削、またはここの部分はこうした方がいいじゃないかというのがあれば教えていただきたいです。よろしくお願いします。

c言語

1#include <stdio.h> 2 3void convert(int *answer, int org) { 4 *answer = 0; 5 6 //1の位の数字を求める 7 int last_digit = org % 10; 8 9 //orgの桁数を求める 10 int num_digits = 0; 11 int tmp = org; 12 while (tmp != 0) { 13 num_digits++; 14 tmp /= 10; 15 } 16 17 //answerに1の位の数字を連結する 18 for (int i = 0; i < num_digits; i++) { 19 *answer = *answer * 10 + last_digit; 20 } 21} 22 23int main(void) { 24 int org; 25 int answer = 0; 26 27 //自然数を入力 28 scanf("%d", &org); 29 30 //convert()関数をコール 31 convert(&answer, org); 32 33 //結果を表示 34 printf("%d\n", answer); 35 36 return 0; 37} 38

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

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

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

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

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

y_waiwai

2024/02/11 08:47

提示しているコードではどういう結果となるんでしょうか。 また、それをどういうふうにしたいという話なんでしょう。
supercubo

2024/02/11 08:57

実行結果は、 (入力)123 (出力)333 というようにできたのですが、コードがこの問題の条件をすべて満たしているのかな..と思ったので質問をしました。条件をすべて満たしていないと0点だぞ!と先生に言われたので..。 自分でチェックはしたつもりですが、良ければ詳しい方にもチェックしていただきたいなと思いました。 意図が分かりにくく、申し訳ないです。
jimbe

2024/02/11 12:36

math.h の log10 は使っちゃいけないんでしょうか。
supercubo

2024/02/11 13:22

使うこと自体はOKだと思いますが、log10 が使えるんですか? 何乗かを求めるやつですよね。使い方が全く想像できないです...
jimbe

2024/02/11 13:40

int num_digits = (int)log10(org)+1; とか。
supercubo

2024/02/11 13:48

すごい!そうやって桁数が求まるんですね! 高校数学の知識が使えるとは..知識増えました! ありがとうございます
fana

2024/02/13 01:33

> orgの桁数を求める こういうのは関数にすると若干すっきりするかも. まぁ,問題文の指定のされ方的に別の関数を作るのがOKなのか否かよくわかりませんが. 関数化までしないのだとしても, num_digits の値を求めている部分(line11 ~ line15)を {} で囲むとかすればどうかな.
guest

回答2

0

ベストアンサー

題意をそのままストレートにコード化した簡明なプログラムで良いと思います。
強いて直すなら、4行目の*answer = 0; は18行目のforの直前に移動します。
あとは変数名のtmpをどうするかですが、「じゃあ、おまえなら何という変数名にするんだ?」と問われるとう唸ってしまいます。あとは17行目のコメントの日本語の「数字を連結する」がやや微妙。それくらいしか言うことがないプログラムかと思います。

whileのループ回数と、forのループ回数は常に同じなので、指摘があるように、1つのループにまとめることは可能です。ただ、そちらの方が良いプログラムかというと、「実行時間を出来るだけ短くせよ」とか「文の数を出来るだけ少なくせよ」というような指示が無い限りは、この問題に対する初学者の回答という意味では、今のままの形の方が良いプログラムだと思います。

あるいはShunlyさんも「トリッキーな」とお書きのようなコードにして、同級生を「すごい」と唸らせたいならもっと短いコードを考えるのも良いかと思いますが、コメントを書かないと「すごい」じゃなくて「なんでこれで求まるの?」と思われるかも知れません。

むしろ、質問文に指摘をしたいです。

 一つの自然数(0を含まない)を

は、正確には「一つの自然数(十進数表記のどの桁にも0を含まない)を」という意味でしょうが、文字通り読むと、「0でない自然数」という意味になります。(横道にそれると https://ja.wikipedia.org/wiki/%E8%87%AA%E7%84%B6%E6%95%B0 をみると分かりますが、「自然数」には「0を含める」と「0を含めない」の2つの流儀があります)
これでは記述が長いし、この問題だと1の位以外はどうでも良いので、ストレートに「1の位が0でない一つの自然数を」で良かったのではないかと思います。
あるいは、00123のようなものも排除したくてこう書いたのなら、「数値」と「数字(または数字文字列、数値文字列、十進数表記)」を区別した日本語記述にしないと駄目です。

最後の

answerは参照渡し

も、一般的なIT用語としての「参照渡し」としては間違った記述です。この引数引き渡し方を「参照渡しというIT用語」だと思ってしまうと、正しい意味での参照渡しのある言語を学ぶ際に困ってしまうかも知れません。

コードがこの問題の条件をすべて満たしているのかな..と思ったので

(a)(b)(c)(d)の条件であれば、main関数の中を書き換えてなければOKでしょう。

投稿2024/02/11 13:23

otn

総合スコア84684

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

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

supercubo

2024/02/11 13:35

詳しく書いてくださってありがとうございます。 解決しました。
otn

2024/02/11 15:19

> 強いて直すなら、4行目の*answer = 0; は18行目のforの直前に移動します。 の理由は考えて分かりましたか? convert関数はコメントの通り3つのパートに別れています。 その前に書いてある *answer = 0; ですが、3つのパートの何処に属するのか、あるいは何処にも属さないのか?を考えると3つ目のパートに属するのでそこに書きます。
supercubo

2024/02/12 02:23

なるほど、*answer = 0; は answer を作っていくパートに属するので、3つ目の部分に書けばいいのですね。 ありがとうございます。
guest

0

間違ってないし、いいんじゃないですかね?
改良するとするなら、桁数を求める必要はないので、ループは1つにできますね。

投稿2024/02/11 09:02

Shunly

総合スコア125

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

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

supercubo

2024/02/11 09:13

回答ありがとうございます。 「ループは1つに」の部分がよくわかりません。具体的にどこをどう変えれば良いのでしょうか?
Shunly

2024/02/11 09:39

今桁数を求めるwhileループとanswerを作成するforループがありますよね?これは1つにできます。 学校の課題なので方法は頭を捻ってみてください。 convert関数は少しトリッキーな方法を使って5ステップが最短じゃないかな。
supercubo

2024/02/11 09:44

もっと簡潔にできるんですね... 悩んでみます。
jimbe

2024/02/11 13:43 編集

トリッキーがどんなか分かりませんが {} 省略無しで 4 行なります。 *answer = 0; for(int last_digit=org%10; org>0; org/=10) { *answer = *answer * 10 + last_digit; }
supercubo

2024/02/11 13:52

そんなfor文の書き方があるんですね。まとまって短くなりますね。ありがとうございます!
melian

2024/02/11 14:57

answer は main 関数内で初期化されているので以下の様に書いてもよいかと。 void convert(int *answer, int org) { for(int last_digit=org%10; org>0; org/=10,*answer=(*answer*10)+last_digit); }
jimbe

2024/02/13 05:57

まぁ、ポインタ自体とは全然関係無い部分ですのでどこまで弄るか拘るかって感じですね^^;
Shunly

2024/02/13 15:31

確かにforで詰め込んだらさらに減りますね、do{~}while(org/=10);で考えてたのが余計でした、、、
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問