配列とポインタについて

このQ&Aのポイント
  • C言語を独学で始めたばかりの者です。ポインタのところまでいきましたが、以下のプログラムを配列で書き替えようと思ったのですが、test4ができません。
  • 配列で書き換えたい箇所は、test4の部分です。配列による書き換え方法を教えていただきたいです。
  • プログラムの最後のtest4を配列で書く方法について教えてください。
回答を見る
  • ベストアンサー

配列とポインタについて

C言語を独学で始めたばかりの者です。 ポインタのところまでいきましたが、以下のプログラムを配列で書き替えようと思ったのですが、test4ができません。test1から3 までは配列を使って書けました。 #include <stdio.h> main() { char s[10]; char *p; strcpy(s, "ABCDE"); p=s; printf("------test1\n"); printf("s=%s p=%s\n", s, p); printf("------test2\n"); putchar(*p); putchar(*(p+1)); putchar(*(p+2)); putchar('\n'); printf("------test3\n"); *p='m'; *(p+1)='n'; printf("s=%s\n", s); printf("------test4\n"); while(*p) { *p=*p+1; ++p; } printf("s=%s\n", s); } この最後のtest4を配列で書くとどうなるのでしょうか。質問文が長くて申し訳ないのですが、お願いいたします。

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

  • ベストアンサー
  • human_7
  • ベストアンサー率29% (15/51)
回答No.6

#1,#3,#5です pはポインタですよね?であれば、 p=s;を行った後の >for(i=0; i<10; ++i) p[i]=s[i]; のコードは意味が無いです。p[i]とs[i]はまったく同じメモリアドレスを指しているので同じメモリの値を代入しています。 そして、p[0]やp[1]に代入すればそれはs[0]、s[1]に代入しているのと同じことになります。 ここまでで重要なのは、あくまでもp=s;を行った直後であるということです。仮にp=s;の後でp++;が実行されたとするとp[i]とs[i]が同じメモリを指すのではなく、p[i-1]とs[i]が同じメモリを指すことになるのです。p自身が指すポイントと添え字を考慮して指すポイントが存在してきます。 後半の方の p[0]='m'; p[1]='n'; i=0; while(p[i]) { p[i]=p[i]+1; i++; } この部分についてですが、まずpがどこを指すかが問題で場合によっては実行されるコードはとんでもない事をしでかすことになります。例えばp[0]='m';の直前までにp++;がされていたとするとp[0]='m';では"AmCDE"を作り上げていることになるのです。これがp+=10;などとなっていたとすると...実行コードを置き換えることになるかも知れません。p[0]='m';の直前にp=s;をしておけば今回のテストでは安全だと言えるでしょう。

tuburi
質問者

お礼

わかりました。ありがとうございました!!

その他の回答 (5)

  • human_7
  • ベストアンサー率29% (15/51)
回答No.5

#1,#3です >この最後のtest4を配列で書くとどうなるのでしょうか。質問文が長くて申し訳ないのですが、お願いいたします。 ということは、今はtest4はポインタで書いているのを配列ではどう書けば良い?ということですか? ちょっと質問を勘違いしていました。 こういうことでしょうか?これには添え字が必要です(ここではi) printf("------test5\n"); i=0; while(s[i]) { s[i]=s[i]+1; i++; } printf("s=%s\n", s);

tuburi
質問者

補足

>ということは、今はtest4はポインタで書いているのを配列ではどう書けば良い?ということですか? そうです。ありがとうございます!一つずらすには s[i]=s[i]+1 とやればいいんですね。とても参考になりました。 ただ、少し疑問なのですが、配列s[10]とp[10]を使って、pをいろいろいじって、その値をsに代入するというのは、可能なんでしょうか。例えば、 i=0; while(p[i]) { p[i]=p[i]+1; i++; } として、その後に for(i=0; i<10; ++i) p[i]=s[i]; printf("s=%s\n", s); としたときは、sにpの値が代入されて出てきますが、 p[0]='m'; p[1]='n'; i=0; while(p[i]) { p[i]=p[i]+1; i++; } for(i=0; i<10; ++i) p[i]=s[i]; printf("s=%s\n", s); とすると、sはnoDEFとは出ません。これはどういうことなんでしょうか。

  • uyama33
  • ベストアンサー率30% (137/450)
回答No.4

uyama33 です。 間違えました。 すみません。

  • human_7
  • ベストアンサー率29% (15/51)
回答No.3

すみませんが、test4の結果はどんな文字を期待されてますか?

tuburi
質問者

補足

noDEF という文字が表示されることを期待しています。 つまりmnCDEを一つづつ次の文字にしてnoDEFとしたいのですが。

  • uyama33
  • ベストアンサー率30% (137/450)
回答No.2

printf("------test4\n"); while(*p) { *p=*p+1; ++p; } printf("s=%s\n", s); } これを、 printf("------test4\n"); while(*p) { *p=*(p+1); ++p; } printf("s=%s\n", s); } としてください。

  • human_7
  • ベストアンサー率29% (15/51)
回答No.1

このtestは書かれたコードのままですか?であれば、test3が終わった時点でpは\0を差している様に思います。なのでtest4で何も表示されないのでは無いでしょうか? test4の直前にもp=s;を実行してみると判ると思います。

tuburi
質問者

補足

はい、書かれたコ-ドのままです。 実行すると、 ------test1 s=ABCDE p=ABCDE ------test2 ABC ------test3 s=mnCDE ------test4 s=noDEF と、表示されるんですが。

関連するQ&A

  • ポインタと配列

    初歩的な質問なんですが、 #include <stdio.h> #include <string.h> main() { char ss[10]; char *p; strcpy(ss,"ABCDE"); p=ss; while(*p){ *p=*p+1; ++p; } printf("ss=%s\n",ss); } で実行結果が ss=BCDEF になります。 while(*p){ *p=*p+1; ++p; } の部分がどうしても理解できません。 参考書にも、解説が載ってなくて困っています。 ご教授宜しくお願いします。

  • 配列とポインタについて

    #include <stdio.h> int main() { char x[3]; char *y; x[0]='a'; x[1]='b'; x[2]='\0'; y="abc"; printf("xの値は%s\n",x); printf("yの値は%s\n",y); } 通常の配列宣言では、このままだと文字列をまとめて 代入できないのに対して、ポインタ変数ならまとめて代入することができるのは何故ですか?そういう仕組みだと言われてしまえば、それまでなんですが・・・

  • ポインタについて

    今初めてポインタというものを勉強しております。 よろしくお願いします。 ◎1---------------------------------- #include<stdio.h> int main(void) { int mydt=1234; int *pt; pt=&mydt; printf("*pt=%d\n",*pt); printf("&mydt=%p\n",&mydt); return 0; } --------------------------------------- ◎1のようにmydtのアドレスをポインタptに代入すれば、このプログラムは正常に動きました。 ◎2----------------------------------- #include<stdio.h> int main(void) { int mydt=1234; int *pt=&mydt; printf("*pt=%d\n",*pt); printf("&mydt=%p\n",&mydt); return 0; } ---------------------------------------- ◎2で「int *pt=&mydt;」があまりどういう意味かはわかりませんが、これも正常に動きました。 ◎3------------------------------------ #include<stdio.h> int main(void) { int mydt=1234; int *pt; *pt=&mydt printf("*pt=%d\n",*pt); printf("&mydt=%p\n",&mydt); return 0; } -------------------------------------- ◎3のように◎2と違って「*pt=&mydt」の代入を後から行うと、「'=' : 'int *__w64 ' から 'int' に変換できません。」といったようなエラーが起きてしまいます。 ◎1と◎2の違い、後何故◎3はダメなのかがわかりません。 教えていただけると嬉しいです。 後補足として、配列とポインタについてですが、 ◎4------------------------------ char ss[10]="ABCDE"; char *ssp=ss; --------------------------------- ◎5---------------------------- char ss[10]="ABCDE"; char *ssp; ssp=ss; -------------------------------- ◎4と◎5も同じような事だとは思いますが違いを教えていただけると嬉しいです。 よろしくお願いします。

  • 配列やポインタに文字列を設定することについて

    ◎1------------------------- #include<stdio.h> int main(void) { char ss[80]; scanf("%s",ss); printf("%s\n",ss); return 0; } ---------------------------- ◎2--------------------------- #include<stdio.h> int main(void) { char *ss="abcde"; printf("%s\n",ss); return 0; } ------------------------- ◎3---------------------- #include<stdio.h> int main(void) { char *ss; ss="abcde"; printf("%s\n",ss); return 0; } ------------------------- 以上3つプログラムで疑問をいだいたのですが、 まず◎1で、これは例えば、 cahr ss[80]="abc"; のように配列ssに文字列"abc"そのものを入れているのか、 char *ss="xyz"; のようにまず"xyz"という文字列をメモリ上のどこかに設定し、その先頭番地をssに代入しているのか、どちらの考えでいいのかわかりません。 次に、◎2、3ではどちらも正常に実行できたのですが、特に◎3で「ss="abcde";」と記述していますが、ssにはアドレスを代入するという認識かあるのですが、文字列定数を代入しても問題ないのか?という疑問があります。 教えていただけたら嬉しいです。

  • ポインタと配列

    次のソースで、結果表示でポインタを使いたいのですが、うまくいきません。1件しか表示されないのです。 ポインタの扱いがおかしいのだと思いますが、どうしたらよいでしょうか? #include <stdio.h> #include <string.h> int search(char key[256],FILE *fp,char *result[256][256]); main(void) { FILE *fp; int rep,n,i; char x[256],key[256],*result[256][256]; printf("検索キーワードを入力してください。\n" "キーワード>"); gets(key); if((fp=fopen("personal.txt","r"))==NULL) { printf("ファイルをオープンできません\n"); exit(1); } printf("=====検索結果=====\n"); n=search(key,fp,result); for(i=0;i<n;i++) { printf("%s\n",result[i]); } printf("検索結果:%d件です。\n",n); fclose(fp); } int search(char key[256],FILE *fp,char *result[256][256]) { int n=0; char *p,word[256],*name; while((p=fgets(word,256,fp))!=NULL) { if(strstr(word,key)!=NULL) { name=strtok(p," "); strcpy(result[n],name); n++; } } return n; } 実行すると、下の警告がでます。 illegal pointer combination(param)

  • char型ポインタ

    よくプログラムで charポインタだけ指定して、 #include<stdio.h> int main(){ char* p; p = "abcdef"; printf("%s",p); return 0; } のようにしているのをみかけますが、 メモリーを確保していなくても問題ないのでしょうか? char* p; p = (char*)malloc(7); strcpy(p,"abcdef"); としたのと同じでしょうか?

  • ポインタの問題です

    学校の課題である文字列をポインタを使って逆順に表示するというプログラムを作ったのですが、「問題で引数で与えられた文字列を逆順とする関数を作成せよ.ただし文字数が最大256文字であると仮定して良い.」ということなんですが、課題が求めている答えと自分が作ったプログラムがあっているか確認お願いします。 #include <stdio.h> void reverseWord(char *str); void main(void) { char *str = "sapporo"; char *p, *q; printf("元: %s\n", str); p = q = str; while (*q != '\0') q++; printf("逆順:"); while (q >= p) putchar(*q--); printf("\n"); } よろしくお願いします。

  • ポインタ?

    #include <stdio.h> main() { char s[] = "I love cat and dog."; char c = 'a'; char *p = s; int n = 0; printf("\"%s\"の中から\'%c\'をさがします。\n", s, c); while(*p != '\0') { if(*p == c) { printf("%d番目で発見しました。\n", p - s + 1); ++n; } ++p; } if(n == 0) { printf("1つも見つかりませんでした。\n"); } else printf("全部で%d個見つかりました。\n", n); return 0; } わからないので質問したいのですが、これは「Cの絵本」という、 本に出ているサンプルプログラムです。 わからないところは、 12行目の、printf("%d番目で発見しました。\n", p - s + 1); ところです。その、「p - s」のところが特にわかりません。 ポインタって言うのは、アドレスを格納する変数ですよね? その、pからsを引いても0になるんじゃないかと思って、理解が できません。どうして、このp-sで、cの位置が発見できるのかが 理解できません。最後の+1は配列が0から始まるんで+1にすれば いいのはわかるんですが、p-sでどんなことが起きているかが 理解できなくて。ポインタをちゃんと理解できていないから、 こういった疑問が出てくるんですかね? ほかの参考書も本屋さんに行って見てみようと思っているんですが、 どなたか教えていただけませんか? よろしくお願いします。

  • ポインタ配列

    配列をポインタでとって、配列要素を足していこうと思ったのですが、 #include <stdio.h> int main (void) { int p[11]={11,23,43,66,54,67,51,88,22,43,-1}; int *e=p; int x=0; int i=0; while( *e!=-1 ) { x + = ( * (e+i) ); i++; } printf("%d\n",x); return 0; } x = ( * ( e+i ) ); ↑この部分がなぜだめなのか理解できません どなたか教えてくださるとありがたいです

  • 文字列を表すための配列とポインタ

    文字列を表すための配列とポインタ  配列とポインタは同様に扱えるもの、と思って、次のプログラムを作りました。処理系は、Visual Studio 2010 コマンドプロンプトです。 #include <stdio.h> void main(void) { char a[256]; char *b; printf("文字列を入力してください。\n"); printf("例「abcde」\n\n"); printf("配列型文字列を使います。\n"); scanf("%s", a); printf("文字列は%sです。\n\n", a); printf("ポインタ型文字列を使います。\n"); scanf("%s", b); printf("文字列は%sです。\n", b); }  すると、まずコンパイル時に、 「warning C4700: 初期化されていないローカル変数'b'が使用されます」 と表示されました。そして、実行すると、「配列型文字列」の方は問題ないのですが、「ポインタ型文字列」の方の実行後に、 「x.exeは動作を停止しました。 問題が発生したため、プログラムが正しく動作しなくなりま した。プログラムは閉じられ、解決策がある場合は Windowsから通知されます。」 と表示され、エラーとして終了してしまいます。 「char *b;」 と宣言するところが問題のようですが、なぜなのかが分かりません。どなたか、解説をお願いします。

専門家に質問してみよう