• ベストアンサー

C言語での質問です。

いきなりですが、 char str[3] = "AAA"; char *str = "AAA"; 先頭のアドレスを両方とも仮に0番として上記の2つを比べた場合、0番地、1番地、2番地に入る値にそれぞれ違いはあるのでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

「先頭のアドレスを両方とも」という意味が不明です。 あと、上の char str[3]; は配列のサイズが危険です。 char str[3] = "AAA"; は、str[3]という配列を"AAA"で初期化しているので、str[3]の中に各々'A'の値が入ります。 char *str = "AAA"; の方は"AAA"という文字列リテラルのポインタを、strに代入しているだけです。 「str」が0番地、"AAA"が100番地にあったとすると、 0番地の値は上が'A'ですが、下は100(この値は処理系によって違う場合がある)となります。

teso5631
質問者

お礼

違いがよくわかり、助かりました。 ありがとうございました。

その他の回答 (2)

  • shinh
  • ベストアンサー率39% (363/926)
回答No.3

>char str[3] = "AAA"; は 間違いですね コンパイルしたら エラーがでました。 仮に (1)char str[3] = {'A','A','A'}; (2)char *str = "AAA"; として (1)は 1バイトの領域を3個 とってます。 0番地 [] 1番地 [] 2番地 [] (2)は、(32ビット処理系として) char型のポインターを入れる領域をとっているので 4バイト 取ってます。 (この変数に入る(入れる)のは 32ビットのchar型のポインター です。) 0番地 [] 1番地 [] 2番地 [] 3番地 [] (1)の場合は 0番地  'A' 1番地  'A' 2番地  'A' (2)の場合は (リトルエンディアンとして) 仮に ”AAA"を割り付けた番地を0x01020304とすると 0x01020304番地  'A'       5番地  'A'       62番地  'A' str 0番地   0x04    1番地   0x03    2番地   0x02    3番地   0x01 となります。

teso5631
質問者

お礼

わざわざ試してもいただき、ありがとうございました。 納得できました。

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.2

0~2番地に入る値は、前者も後者も同じ(すべて'A')です。 ただし、0~2番地の内容を書き換えられるのに対し、 後者は書き換えられません。たぶん、実行時にエラーが出ます。

teso5631
質問者

お礼

回答ありがとうございました。

関連するQ&A

  • C言語の型キャスト

    C言語入門者です、よろしくお願いします C言語の型キャストについて教えてください 参考サイトで以下のようになってました char str[8] = "ABC"; char *ptr; ptr = (char*)str; printf("char型ポインタのアドレス先の値は: %s\n", ptr); この型キャストって意味ありますか? キャストしようがしなかろうがptrに収まるのはstrの先頭アドレスですよね? ただ型キャストを説明するためだけにこのような形にしているのか 意味がある型キャストなのかが解らず迷ってます

  • C言語の型と配列

    char* str[10]={"a","b"}; char* str2="c"; としたときにstr=str2とすると 型が合わないといったエラーが出ます。 でもstrって結局はポインタの配列の先頭要素のアドレスですよね。 ポインタにポインタを入れているので通るのかなと思ったんですけど、 配列で宣言するとポインタにも型がつくのでしょうか? この例だと strは char * を10個持つ配列をさすポインタ  で、 str2はchar *をさすポインタ みたいなかんじです。 質問の意味がわかりにくいですが、ご指摘をいただければ補足しますので よろしくお願いします。

  • C言語のポインタと配列について

    下のコードについて2つ質問があります。 (1) char *p; p = str; ならわかるのですが、なぜ型が違う char *p = str; のような代入がOKなのでしょうか。文字列をコピーするときの   *p = *str; と比較して、とても違和感があります。  str は引数で受けた文字列の先頭アドレス。 (2)   char *str;   str = " 1 23 4 5"; と   char str[] = " 1 23 4 5"; との違いがよくわかりません。 #include <stdio.h> #include <ctype.h> void TrimSpace(char *str) {   char *p = str;        // (1)型が違うのになぜこんな代入をするのか?      while (*str != '\0') {     if ( !isspace(*str) ) {       *p = *str;      // この代入は自然       p++;     }     str++;   }   *p = '\0'; } int main(void) {      //char *str;   //str = " 1 23 4 5";     (2)これでは空白を詰めた後の文字列が表示されないのはなぜか?      char str[] = " 1 23 4 5"; //これで OK   printf("空白を詰める前:\"%s\"\n", str);   TrimSpace(str);   printf("空白を詰めた後:\"%s\"\n", str);   return 0; }

  • C言語のポインタにの動作について

       以下のコードで、DelHalfSpc() において引数 str は str++ でカウントされ、ループを抜けた時点では文字列の末尾を指しているはずですが、なぜ呼び出し側の main()の char str[] には正しい値が入るのでしょうか? char *DelHalfSpc(char *str) {   //char *dmy = str; → char * という型の変数 dmy の宣言   char *dmy, *Res;   Res = dmy = str; // Res は常に先頭アドレスを指す   while (*str != '\0') {     if ( *str != ' ' ) {       *dmy = *str;       dmy++;     }     str++;   }   //ループを抜けたこの時点で str は文字列の末尾を指しているはず   *dmy = '\0';   return Res;   //ここを return str とするとヌル文字列を返す } int main(void) {   char str[] = " 1 23 4 5";   printf("空白削除前:\"%s\"\n", str);   printf("空白削除後:\"%s\"\n", DelHalfSpc(str));   printf("str も変化:\"%s\"\n", str); //なぜ正しい結果が表示されるのか?   return 0; } 【結果】 ----------------------- 空白削除前:" 1 23 4 5" 空白削除後:"12345" str も変化:"12345"

  • C言語の配列について質問です。

    配列の添え字に別の配列を指定するような以下の処理について 質問です。 #include <stdio.h> int main(void) {    int k = 0;    int kn = 0;    char str[256];    char key[] = "ABCD";    kn = strlen(key);    for(k=0; k<kn-1; k++) {    str[key[k]] = kn-k-1;    } } 上記についてですが、for文の中で "str[key[k]]"とありますが、 ループ処理にともなって配列str[] の添え字は、str[A], str[B], str[C] となるのでしょうか?? その場合、結果的に配列str[]の各要素にはどのような値が格納され るのでしょうか? そもそも、配列の添え字に対して別の配列を指定した場合の動きが よくわかりません。 どなたか教えて頂けますか??

  • C言語のint型の配列が分かりません

    #include<stdio.h> int main(void) { int str[ ]={0,1,2} printf("%s\n", str); return 0; } というプログラムをC言語でつくってみましたが動きません.(012と表示されて欲しかったのですが) int str[ ]={1,2,3}の部分をchar str[ ]={'0','1','2'}とすれば動きます. そこで質問なのですが, printf("~%s~", (配列名));  はchar型の配列にしか適応できないのですか? ※追記 puts関数の定義は int puts (const char *str); であるそうなので char型の仮引数にはchar型のアドレスを渡さなければいけません. ではprintf関数の定義は一体どんなものなのですか?

  • C言語の基礎的な質問---文字配列の初期化

    C言語の配列の初期化に関する質問です。 もし規格によって回答が異なる場合は、ANSIのCということにしてください。 関数の中に、 char str[ ]="ABC"; (イ) という宣言があるとします。(staticは付きません。) これは、 char str[ ]={'A', 'B', 'C', '\0'}; (ロ) と全く同じ意味でしょうか。  似て非なるものに char *str="ABC"; (ハ) というものがあります。この場合は、 strとは違うところに"ABC"('C'の次には'\0'があります。)という領域が確保されていて、 その先頭アドレスでstrが初期化されるのですよね。 (イ)(ロ)(ハ)のいずれの場合も関数の中に書かれているとすれば、 いずれもstrは自動変数で、関数実行時にstrの領域が確保されますよね。 (イ)は配列strの領域が確保されるときに、 配列strとは別のところにある"ABC"という領域の内容を、コピーして設定する、 ということでしょうか。 (ロ)は、配列の領域確保時にstr[0]を'A'で、str[1]を'B'で、str[2]を'C'で、str[3]を'\0'で、初期化する、 ということで、 配列とは別のところには"ABC"という領域はない、 という考えでよろしいでしょうか。 もしそうだとしたら、配列とは別のところに"ABC"という領域があるかどうかという点で(イ)と(ロ)は異なることになりますが、そう考えてよろしいのでしょうか。 それとも、そういうことは処理系に依存することなんでしょうか。

  • C言語

    以下のC言語のプログラムを教えてください。 お願いします。 (1)標準入力から文字列(2 文字以上)を入力し,文字数を計上すると共に,入力された文字列の逆順に入れ替える処理を実現してください.なお,以下の要件を満たしたプログラムを作成してください. ・ 入力された文字列は,char 型の配列(要素数50)で受け取ること ・ 文字数を計上するcount 関数(引数:配列のアドレス,戻り値:文字数)を定義 し,main 関数より呼び出すこと ・ 文字列を逆順に入れ替えるreverse 関数(引数:配列のアドレス,戻り値:無し) を定義し,main 関数より呼び出すこと ・ 標準出力の処理は,main 関数で記述すること 【プロトタイプ宣言】 int count(char *str); void reverse(char *str); 【実行結果】 文字列を入力してください(2 文字以上) apple 文字数 = 5 入れ換え前 apple 入れ換え後 elppa (2)char 型の配列(要素数50)を2 つ宣言し,標準入力から2 つの文字列を入力してください.そして,格納した字列を入れ替える関数(swapstr 関数)を作成し,入れ替え前と入れ替え後の配列内の値(文字列)を配列名とともに標準出力するプログラムを作成してください. 【プロトタイプ宣言】 void swapstr(char *str1, char *str2); 【実行結果】 2 つの文字列を入力してください apple strawberry 入れ換え前 配列str1 = apple 配列str2 = strawberry 入れ換え後 配列str1 = strawberry 配列str2 = apple

  • 計算機言語(C言語)の課題です。

    ポインタstrが文字列の先頭文字を指しているとき、その文字列に含まれる数字、符号’+’及び’-’以外の文字を削除する関数 void del_char(char *str) を作成しなさい。例えば、A-+1BC2+3D\0であれば-123\0とする。なお、符号についても、数字より前にある最初のもの以外は、削除するものとする。

  • C言語(ポインタ)について

    某参考書にて下記のような問題があって、その解答について分からないことがあります。 <問題> strcat()の独自バージョンとしてmystrcat()という関数を作成するとともに、この関数が正しく動作することを確認するための短いプログラムを作成してください。 <解答> #include <stdio.h> #include <string.h> void mystrcat(char *to, char *from); int main(void) { char str[80]; strcpy(str,"最初の部分"); mystrcat(str, " 2番目の部分"); printf(str); return 0; } void mystrcat(char *to, char *from) { /* toの最後を探す */ while(*to) to++; /* 文字列を連結する */ while(*from) *to++ = *from++; /* ヌル終端文字を付加する */ *to = '\0'; } 解答の*to++ = *from++;までは、なんとか何をしているのかは分かったのですが、最後の*to = '\0'という部分がよく分かりません。 なぜ、ヌル終端文字を付加する必要があるのでしょうか? 初歩的なことかもしれませんが、分からず困っているのでよろしくお願いします。

専門家に質問してみよう