プロが教えるわが家の防犯対策術!

 自分で考えてみようと思って考えたプログラムなのですが、ポインタを用いてabc・・・・・とアルファベットをどう進めて行けばいいか分かりません。
 出来れば見本のプログラムを書いて頂ければうれしいです。
 
 それと、””と’’と{}の使い分けは何ですか?

 私が今考えているのは
 「a[100]という数列にランダムに入っているアルファベットはそれぞれ何回出て  きているかabcd・・・・・・zの順に出力する」
  プログラムです。
 
 下が考えてみたものです。


#include<stdio.h>
main(void)
{
static char a[100]=’adhfdfhhlljyerhcvcjhljeyruqqruqruietyiucvnasqasdjh’;
static int count[100];
int I;
char *alpha,*suu;
alpha=a;
I=0;
while(*alpha!=’\0’)
{
for(*suu=’a’;*suu<=’z’;*suu+=’b’-‘a’)
{
if(*alpha==*suu) ++count[I];
++I;
}
}
for(*suu=’a’,I=0;*suu<=’z’;++I,*suu+=’b’-‘a’;) printf(“%c の出で来た回数は %d\n”,*suu,count[I]);
}

教えて!goo グレード

A 回答 (4件)

こんにちは。

itohhといいます。

まずは、""と''の違いですが、文字列を指定したい場合""にします、''のときは、文字の値
そのものを扱う場合です。

配列(a)の中には、半角英小文字のみ設定されているという条件でサンプルを載せます。

void main(void)
{
  static char a[100]="adhfdfhhlljyerhcvcjhljeyruqqruqruietyiucvnasqasdjh"; // (1)
  static int count[26]; // (2)
  int idx;
  char *alpha;
  int suu;
  
  memset( count, 0x00, sizeof(int)*26 ); // (3)
  
  // 文字列の最後まで出現頻度をカウントします。
  for( alpha=a; *alpha!='\0'; alpha++ ) // (4)
  {
    // 'a'を配列の0番目に'z'を25番目としてカウントします。
    idx = *alpha - 'a'; // (5)
    count[idx]++;
  }

  // 'a'から'z'までの件数を出力します。
  for(suu='a',idx=0; suu<='z' ; idx++,suu++) printf("%cの出で来た回数は%d\n",suu,count[idx]);
}

注意:各行の先頭に全角スペースを入れていますのでカット&コピーするときは気を付けてください。

説明:
(1)配列に初期設定する場合、""で囲みます。
(2)アルファベットは26文字なので...
(3)件数のカウンタをまとめてzeroクリアします。
(4)alphaの指すアドレスが0x00になるまでループします。
(5)上記でも書きましたが「''」で囲む場合は、文字の値となります、この場合、「'a'」
   ですから、0x61という値と同じです。

   配列「a」のはじめの文字は「'a'」ですから引き算すると「0」になり、idxに設定されます。
   配列「a」の2番目の文字は「'd'」ですから引き算すると「3」になり、idxに設定されます。

   これを最後まで繰り返すと「a」から「z」までの配列「count」に出現頻度がカウントされます。

如何でしょうか?
もし、判らないところがあれば、補足してください。

この回答への補足

アドバイスありがとうございます。

>memset( count, 0x00, sizeof(int)*26 );
これはmemsetという関数」なのでしょうか(無知ですいません。)?

>idx = *alpha - 'a'; // (5)
*alphaはchar型ではないのでしょうか?値をもつのですか?

すいませんが教えてください。
    

補足日時:2002/05/24 04:50
    • good
    • 0

こんにちは。

itohhといいます。

>>memset( count, 0x00, sizeof(int)*26 );
>これはmemsetという関数」なのでしょうか(無知ですいません。)?
そのとおりです。
文字列を操作するのに良く使用する関数は。
memset関数:指定の文字で埋める
memcpy関数:文字列をコピーする
memcmp関数:文字列を比較する
strcpy関数:文字列をコピーする(自動的に文字列の最後に「¥0」を代入する)
などです。一度、関数マニュアルを見てください。

>>idx = *alpha - 'a'; // (5)
>*alphaはchar型ではないのでしょうか?値をもつのですか?
alphaは、char型のポインタです。
しかし、*alphaは、char型です。ですから、1バイトを参照することになります。
char型とは、ASCIIコードが設定されていると言うことです。
'a'なら0x61が'b'なら0x62が'z'なら0x7Aが設定されています。ASCIIコード一覧を確認してみてください。

例えば。
*alphaに入っている1バイト目のASCIIコードは、'a'=0x61で、2バイト目は、'd'=0x64です。
(5)では、ASCIIコード同士で引き算をしているということです。

c言語の場合、足し算したからといって文字列が連結されるというわけでもないし、引き算した
からといって文字列が分割されるわけではないのです。
    • good
    • 0

こんにちは。

itohhといいます。

すみません、chikako-imagawaさんが考えたソースのアドバイスを忘れていました。

>#include<stdio.h>
>main(void)
>{
>  static char a[100]=’adhfdfhhlljyerhcvcjhljeyruqqruqruietyiucvnasqasdjh’;
「""」と「''」の間違いですね。

>  static int count[100];
>  int I;
>  char *alpha,*suu;
>  alpha=a;
>  I=0;
>  while(*alpha!=’\0’)
>  {
>    for(*suu=’a’;*suu<=’z’;*suu+=’b’-‘a’)
suuは、charポインタです、実態がないところには、「'a'」は設定できません。
suuは、int型にするべきでしょう。

>    {
>      if(*alpha==*suu) ++count[I];
>      ++I;
>    }
このループは、「'a'」から「'z'」まで行いますが、「I」カウンタがalphaの2文字目以降も
どんどんカウントアップされ続けてしまいます。
「*suu+=’b’-‘a’」で1づつカウントアップするということが、お判りなのですから
forループを使わない方法(わたしが示したサンプルのように)を考えられるのではないですか?
もし、forループを使うのでしたら、「for(suu='a' ,I=0;」のように行うべきでしょう。

>  }
このwhileループでは、「alpha」をカウントアップしていません。


>  for(*suu=’a’,I=0;*suu<=’z’;++I,*suu+=’b’-‘a’;) printf(“%c の出で来た回数は %d\n”,*suu,count[I]);
これも、suuは、charポインタです、実態がないところには、「'a'」は設定できません。

>}
    • good
    • 0

C&C++は門外漢なんですが、考え方の参考になりましたら。




配列aの要素を先頭から終端まで見ていく際、出現するのはa-zですよね。

最後に出現回数をa-zの順で表示することでもあるし、
判定対象の文字毎にa-zのループを回すのではなく、
「文字コードからカウント用の配列の添え字を求める」のが簡単では?
(カウント用の配列countは26あれば良い)
    • good
    • 1

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

教えて!goo グレード

このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング