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

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

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

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

Q&A

解決済

2回答

718閲覧

C言語 特定英字の個数のプログラムについて

za-to

総合スコア7

C

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

0グッド

1クリップ

投稿2021/06/25 01:59

編集2021/06/25 05:58
#include<stdio.h> #include<ctype.h>  「int main(int argc, char *argv[]){ #define INDEX(x)(x-'a') int c[INDEX('z'+1)]={0}; 」 int ch; for(;(ch=getchar())!=EOF;){ if(isalpha(ch)) c[INDEX(tolower(ch))]++; } for(ch='a'; ch<='z'; ch++){ if(c[INDEX(ch)]!=0) printf("%c:%d\n",ch,c[INDEX(ch)]); } return 0;

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

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

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

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

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

za-to

2021/06/25 02:51

すみません、なぜか太字と巨大化してしまいました。
neconekocat

2021/06/25 03:36

ちゃんと読みやすく書き直してもらえれば答えますよ 自力で考えたい場合はASCIIコードとか調べたら解決できるかも
WoodenHamlet

2021/06/25 04:20

エディターの上の、ボタンが並んでいるところに<code>ボタンがありますね?それを使って、ソースコードをコードそのままでページに出すことができます。プレビューをよく見ながら質問を修正してください。
WoodenHamlet

2021/06/25 04:23

エディター右上のテンプレートを使うのも良いでしょう。ただ使う上で一つ注意してほしいのですが、「ここにより詳細な情報を記載してください。」など、テンプレートそのままの文言が残っていたりすると、飽くまで個人的にですが、回答する気は起きません。
za-to

2021/06/25 05:58

修正しました。 「」で囲まれた部分の意味をご教授お願いいたします。
za-to

2021/06/25 05:58

ご指摘ありがとうございました。
neconekocat

2021/06/25 08:53

rubato6809さんの回答でほぼ100%説明が付いてるんですが私の回答要りますかね…? あと質問文から最初の質問内容が消えてるからそこは戻しておいてください。
za-to

2021/06/25 10:03

一応、全ての方が回答した後に判断した方が良いのかと思いました。
guest

回答2

0

ベストアンサー

int main(int argc, char *argv[]) {
main()関数の冒頭部分で、戻り値の型と引数の型を示している…程度でよさそうですね。

#define INDEX(x) (x-'a')

前提となるアスキーコード表を確認すると
'a' == 0x61 == 97
'z' == 0x7a == 122 です。
アルファベットは 'a' ~ 'z' の26文字あるので、出現回数を保持する配列の要素数は26必要です。したがって int c[26]; としたい。

そのうえで、例えば'a' の出現回数を c['a'] とでもしたいところですが、それだと c[97] となってしまってダメ。そこで
'a' => 0 (== 'a' - 'a')
'b' => 1 (== 'b' - 'a')
:
'z' => 25 (== 'z' - 'a')
と変換するマクロ INDEX(x) を作ればよい。見ての通り、INDEX(x) マクロは (x - 'a') を計算すれば良いことがわかる。
INDEX(x) マクロを作れば
c[INDEX(tolower(ch))]++
はchの値が文字コード('a' なら97)のまま、その文字の出現回数を+1できます。
念のため:tolower(ch) は、ch が英大文字であれば小文字に(例えば 'A' を 'a' に)、英小文字はそのまま小文字に変換します。つまり 'A' も 'a' も同じ文字とみなすことになります。

int c[INDEX('z' + 1)] = {0};

ここは、要素数26の配列を定義して(メモリを割り当てて)、その全ての要素を0で初期化しています。

  • INDEX('z'+1) => 'z' + 1 - 'a' => 122 + 1 - 97 => 26 であるから、

int c[INDEX('z' + 1)] は int c[26] と展開される。めでたしめでたし(アルファベットが26文字であることは常識の範疇だから最初から int c[26] = {0}; としても構わないと思う)。

  • int c[INDEX('z'+1)]; としただけだと、メモリは割当られるが、値は不定になってしまう。各文字の出現回数を数えるには、最初の値をすべてを0にしておく(0に初期化する)必要がある。
  • 「= {0}」 の部分で配列の全ての値を0で初期化する。ここに「0」は一個しか書かれていないので c[0] = 0 だけが初期化されるかと思うと、さにあらず。初期値の指定がある場合、初期値が省略された c[1] ~ c[25] も初期値を0にするという約束なので。

P.S.
for(;(ch=getchar())!=EOF;){ でも良いけど
while ((ch = getchar()) != EOF) { で良いのでは。

投稿2021/06/25 04:40

編集2021/06/25 08:31
rubato6809

総合スコア1380

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

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

za-to

2021/06/25 10:05

丁寧な回答ありがとうございました。 わかりやすくて、理解することが出来ました。
guest

0

//int main(int argc, char *argv[]){

mainという関数を定義してます

投稿2021/06/25 02:13

y_waiwai

総合スコア87747

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

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

za-to

2021/06/25 02:55

読みづらくて申し訳ございません。 その後の2行が特にわからないのです。 なぜxから'a'を引いているのか。 int ch[INDEX'z'-1]なのか。 教えて頂けたらと思います。宜しくお願い致します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問