- 締切済み
ポインタとcharについて
文字列ABCDEFGHIJKとあり、それを以下のように表示させるプログラミングを考えています。 ABCDEFGHIJK 全部表示 ACEGIK 1個とばして表示 ADGJ 2個とばして表示 このときポインタを使用することが条件です。 自分は char *s[11]; s[11] = 'A','B','C','D','E','F','G',','H','I','J','K'; int i; for(i=0; i<11; i++) { printf("%s",s[i]); } これでABCDEFGHIJKを表示しようとしましたが、できませんでした。 なぜでいきないのか指摘お願いします。 初歩的なことですみません。
- みんなの回答 (8)
- 専門家の回答
みんなの回答
- NNori
- ベストアンサー率22% (377/1669)
#7です。 訂正します。 char c ; c = 'A','B','C'; とやると c には 'A' が入ります。どうしてかというとカンマ演算子は、= よりも優先順位が低いからです。 つまり、上の式だと、 ( c = 'A' ) , 'B' , 'C' ; と評価されます。 こんなバカなこと普通はしませんよねぇ。
- NNori
- ベストアンサー率22% (377/1669)
余談ですが、 char s[11]; s[11] = 'A','B','C','D','E','F','G','H','I','J','K'; これって、どこが間違いかわかりますか? char s[11] で定義される配列は、0 から 10 までの 11 個分の配列です。 したがって、 s[11] には代入できません。 これは、実行時エラーでコンパイルエラーにはなりません。 そして、問題は右辺です。 'A' とかは、A という1バイト文字の定数です。 まぁ、数字のようなものです。 そして多くの人が忘れているのがカンマです。これはカンマ演算子というやつです。 なので、右辺はエラーにはなりません。 カンマ演算子は、左から右に評価され、カンマ演算子の返値は後の式の結果になります。 つまり、 'A','B','C','D','E','F','G','H','I','J','K' という式は 'K' を返します。 char c; c = 'A','B','C','D','E','F','G','H','I','J','K'; とやると、 c には 'K' が代入されます。
- NNori
- ベストアンサー率22% (377/1669)
試に以下のようなものを実行しましたが上手く行きませんでした。何故でしょうか。 char s[11]; strcpy(s,"ABCDEFGHIJ"); char *p; p = &( s[0] ); printf("%s",*p); ちなみに、1と2の違いは理解できたと思います。 ==== *p だと s[0] のことになりますので、printf したければ printf("%c",*p); となります。この場合 A がprint できるはずです。 文字列として ABCDEFGHIJ を print したければ、 printf("%s",p); となります。 もうちょっとですね。
- harawo
- ベストアンサー率58% (3742/6450)
> このときポインタを使用することが条件です。 なぜ、それが条件なのか?その必然性を説明するのが、最初でしょう。 そういう縛りがなければ、コード自体はきわめてかんたんです。 char s[] = "ABCDEFGHIJK"; int i; char b; for (i = 0; i < 11; i++) // for (i = 0; i < 11; i += 2) 1個とばし // for (i = 0; i < 11; i += 3) 2個とばし { b = s[i]; // (A) printf("%c", b); } printf("\n"); 配列を扱うということは、そのままポインタを扱うことだということです。 「s[]」に対して、「s」は、配列の最初の要素のアドレスを示すポインタです。 なので、「*(s + 1)」は、「s[1]」と同じ意味になり、「s +1」は2番目の要素のアドレスを示すポインタで、「*(s + 1)」は2番目の要素になります。 上のコードの、(A)を、「b = *(s + i);」と書けば、「ポインタを使用したコード」ということになります。(そうでなくても、ポインタを使っていることになるけど)
- osamuy
- ベストアンサー率42% (1231/2878)
おっと、char *s[11]でしたか。だとすると、printfの指摘は間違いで、 > s[11] = 'A','B','C','D','E','F','G',','H','I','J','K'; こっちがおかしい。 a) Cの文法を間違えて覚えている。 b) Cの文字列を理解してない。 c) 単なるケアレスミス。 ――のいずれか、あるいはその全ての可能性が考えられます。
- asuncion
- ベストアンサー率33% (2127/6289)
>s[11] = 'A','B','C','D','E','F','G',','H','I','J','K'; ここでコンパイルエラーが起きてますよね。 どんなエラーメッセージが出ていますか?
- NNori
- ベストアンサー率22% (377/1669)
char *s[11]; これは、char 型をポイントすることができる変数を11個の配列でとります。 題意からポインター型の配列は必要ないことに気づきましたか? まず、文字列 ABCDEFGHIJ というのを文字列で代入することを考えます。 1.文字列変数を用意して代入する 変数の宣言は、文字型の配列である必要があります。 char s[11]; strcpy( s , "ABCDEFGHIJ"); こうすると文字型配列 s の s[0]に A,s[1]にB が代入されます。 2.文字列をメモリ上のいずれかに用意させてポインタだけ持つ char *s = "ABCDEFGHIJ"; こうするとメモリ上のいずれかに ABCDEFGHIJ\0 がとられて一番初めのアドレスが 変数 s に代入されます。 まず1と2の違いを理解してください。 そしてそれぞれ文字列の先頭を示すアドレスを取り出したい場合は次のようになります。 char *po; 1の場合 po = &( s[0] ); これは、s[0] は char 型ですので、そのアドレスを取り出しています。 または po = s; これは、配列のくせに[]をつけないと 自動的に その先頭アドレスを返すという文法をつかっています。 2の場合 po = s; これは、1の場合と異なり、sという変数の値を po に 代入しているだけです。 これが理解できれば、やりたいことが見えてくるのですが、いかがでしょうか?
補足
試に以下のようなものを実行しましたが上手く行きませんでした。何故でしょうか。 char s[11]; strcpy(s,"ABCDEFGHIJ"); char *p; p = &( s[0] ); printf("%s",*p); ちなみに、1と2の違いは理解できたと思います。 上記のようなものができれば、for文とif文で題意のものを作れる気がしますが・・・どうでしょうか?
- osamuy
- ベストアンサー率42% (1231/2878)
> printf("%s",s[i]); ここがおかしい。 a) 書式文字列を間違えて覚えている。 b) Cの文字列を理解していない。 c) たんなるケアレスミス。 ――のいずれか(あるいはそのすべて)の可能性が考えられます。
補足
Microsoft Visual C++ 2010を使ってるのですが「charの値をchar*のエンティティに割り当てることができません」と書かれてあります