• ベストアンサー

ポインタについて

下記<コード1>ではエラーが出ないのに、 <コード2>のように変更すると、 ”error C2105: '++' には左辺値が必要です。” とエラーが出ます。 どうしてなのか教えて下さい。 <コード1> char *str_copy(char *d , const char *s){ char *t=s2; while(*d++=*s++) ; return (t); } int main(void) { char s1[128]="ABCD"; char s2[128]="EFGH"; str_copy(s2,s1); <コード2> int main(void) { char s1[128]="ABCD"; char s2[128]="EFGH"; // str_copy(s2,s1); while(*s2++=*s1++) ;

  • mk1234
  • お礼率94% (1832/1940)

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

  • ベストアンサー
  • leaz024
  • ベストアンサー率75% (398/526)
回答No.4

配列変数名はポインタとして扱えますが、ポインタ変数ではありません。 ポインタ変数が表すアドレスは「変数に格納された値」なので、値の操作によりアドレスの変更ができます。 これに対し、配列変数名が表すアドレスは「変数自身のアドレス」であり、通常の変数で言えば「&変数名」にあたるものです。 このアドレスはコンパイラによって算出されたものであり、メモリ上のどこにも格納されてはいません。 そのような値を「左辺値」として利用することはできません。 (変数自身のアドレスは「定数ポインタ(type * const型)」として扱われます。)

mk1234
質問者

お礼

回答ありがとうございました。 納得できる説明で良く分かりました。

その他の回答 (3)

  • sha-girl
  • ベストアンサー率52% (430/816)
回答No.3

配列名=ポインタというよりは 配列の添え字をとったときにポインタになるというだけです。 配列s1[2]を*(s1+2)というような使い方は可能です。 ポインタに対して*(p1++) p1という数値に1001(番地)がはいっていれば1002(番地)になります(charの場合) しかし配列*(s1++)はそのポインタの移動後の番地を保存しておく場所が確保されていません。 p1 = s1 + 1;だったらokです。

mk1234
質問者

お礼

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

  • ranx
  • ベストアンサー率24% (357/1463)
回答No.2

ポインタは変数、配列は定数。 int a; で a=1; とは書けても 1=a; とは書けない。 それとほぼ同じ。

  • gimmick
  • ベストアンサー率49% (134/270)
回答No.1

>while(*s2++=*s1++) s1++とs2++が問題。配列名には++は適用できません。 #ついでに言うと、コード1の「char *t=s2;」は「char *t=d;」の間違いかな? 標準ライブラリのstrcpyを真似した場合の話だけど。

mk1234
質問者

お礼

回答ありがとうございます。 確かにs1、s2は配列名です。しかしながら、配列名=ポインタであると思っていましたが解釈がおかしいのでしょうか? 事実コード1では、s1、s2のポインタ渡しを行っていると思うのですが・・・

mk1234
質問者

補足

>「char *t=d;」の間違いかな? そうです。あわてて間違えました。

関連するQ&A

  • 文字列のコピーについて

    下記<コード1>と<コード2>はどちらも同じに思えますが、実際には<コード2>は”不正な処理”で終了してしまいます。 いろいろ考えたのですが、どうしても違いが理解できません。 理由がお分かりの方お願いいたします。 <コード1> char *str_copy(char *d , const char *s){ char *t=d; while(*d++=*s++) ; return (t); } int main(void) { char s1[128]="ABCD"; char s2[128]="EFGH"; str_copy(s2,s1); <コード2> char *str_copy(char *d , const char *s){ char *t=d; while(*d++=*s++) //不正な処理 ; return (t); } int main(void) { char s1[128]="ABCD"; char *ptr ="EFGH"; str_copy(ptr,s1);

  • ポインタ

    質問なのですが、このソースのchar *str_copy(char *d, const char *s)関数内のchar *p=d;はなんで、*pにdを入れるか分かりません。それと、このdは、*dなのですか?どうして、while (*d++ = *s++) みたいに*dをつけないんですか?教えてください。宜しくお願いします。 #include <stdio.h> char *str_copy(char *d, const char *s) { char *p=d; while (*d++ = *s++) ; return (p); } int main(void) { char tmp[100]; char st1[100], st2[100],st3[100]; printf("文字列を入力してください:"); scanf("%s",tmp); str_copy(st1,str_copy(st2,tmp)); printf("文字列st1は%sです。\n", st1); printf("文字列st2は%sです。\n", st2); printf("文字列st3は%sです。\n", str_copy(st3,tmp)); return (0); }

  • 関数のポインタ

    char* check(int a,int b,int c) { return(\"yes\"); とした場合char* checkは何を表しているのでしょうか。 また、 char *str_copy(char d[], char s[]) { char *t=d; while(*d++ = *s++) ; return t; とした場合との違いはあるのでしょうか。 ポインタを返すときに*をつけると教わったのですがいまいち理解できなかったのですがどのような処理が行われているのでしょうか、お願いします。

  • 文字列とポインタの問題です。

    #include<stdio.h> int f(char *s); int main(void){ char*str="nasida Institute of Technology"; int i; i=f(str); printf("%s:%d\n",str,i); return 0; } int f(char *s) { int j=0; while(*s!='\0'){ if(*s=='t'){ j++; } s++; } return j; } このプログラムの答えが3になるんですが、if文のとこの動作がよく分からないので、よろしくお願いします。

  • voidポインタ

    教えて頂けますか? 環境は mac osx です。 とあるページのサンプルコード #include <stdio.h> void outString(void *); int main() { int i = 65 ; double d = 10.101; outString(&i); outString(&d); outString("Kitty on your lap"); return 0; } void outString(void *text) { char *str = (char *)text; printf("%s\n" , str); } を実行した次のように表示されました A \301ʡE\2663$@\234\367\377\277A Kitty on your lap 二行目はどういう事になっているのでしょう? ちなみに d = 65.0; で実行しましたが A とは表示されませんでした。 自分の環境のせいでしょうか? よろしくお願いします

  • C言語 ポインタ エラー

    文字列を入力後改行して入力した文字列を出力したいのですが、エラーがでます。 ハンドルされない例外が 0xFEFEFEFE (helloworld.exe) で発生しました: 0xC00001A5: 無効な例外ハンドラー ルーチンが検出されました。 (パラメーター: 0x00000003)。 調べてみましたが、理解できません 何卒よろしくお願いします。 #include <stdio.h> void put_string(const char *str) { while (*str) putchar(*str++); } int main(void) { char str[100]; printf("文字列を入力してください"); scanf_s("%s", str); put_string(str); putchar('\n'); return(0); }

  • ポインタについて

    #include<stdio.h> int main(void) { char str[10]; char *ptr = str; printf("文字列を入力してください。\n"); scanf("%s",ptr); printf("文字列は%sです。",str); return 0; } 上記のプログラムのscanf("%s",ptr);の ptrに&をつけるとなぜ先頭の4文字は入力しても 表示されなくなってしまうのでしょうか? よろしくお願いします。

  • 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; }

  • 構造体へのポインタ

    typedef struct str_tmp_t{ int a; char b; } str_tmp; void main() { str_tmp *str_info; str_info->a = 1; } とした場合、コンパイルエラーは出てはいないのですが、数値を代入している個所で落ちてしまいます。 これを回避するには単純にmallocしてfreeすれば良いのでしょうか? よろしくお願い致します。

  • ポインタで分からないことがあります。

    つい最近C言語の勉強を始め、現在ポインタの勉強をしています。 過去の質問を検索したり、サイトを見てみましたが、一人の力では解決できませんでしたので質問させていただきます。 ポインタのプログラムで、下記のプログラムについて分からないことがありました。 ――――――――――――――――――――――――――――――――― #include <stdio.h> int main (void) { char *str = "abc"; printf ("%s %d %d\n", str, &str, &(*str)); str = "日本語"; printf ("%s %d %d\n", str, &str, &(*str)); return 0; } ――――――――――――――――――――――――――――――――― このプログラムで、「char *str = "abc";」の部分でstrには abcのアドレスが入っていると思っていたのですが、 1度目の「printf ("%s %d %d\n", str, &str, &(*str));」で、 結果が「abc 1245064 4235560」となっているのを見ると 私の見解は間違っている気がします。 「char *str = "abc";」の部分では一体なにが行われているのでしょうか? また、このプログラムをコンパイルして実行した結果が、 abc 1245064 4235560 日本語 1245064 4235574 となったのですが、なぜstrのアドレスは同じなのに、 &(*str)のアドレスは異なるのでしょうか? 質問をまとめますと、以下の2つです。 1.「char *str = "abc";」の部分では一体なにが行われているのでしょうか? 2.「abc」と「日本語」のstrのアドレスは同じなのに、&(*str)のアドレスは異なるのでしょうか? 初心者ですので言葉の足らない部分があるかもしれませんが、ご教授のほどよろしくおねがいします。

専門家に質問してみよう