• ベストアンサー

ポインタについて

#include<stdio.h> int main(void){ int i; char *pt = "Hello World"; char a[11]; pt = &a; for(i=0;i<=11;i++){ printf("%c %x\n",pt,&a[i]); pt++; } return(0); } H abcd80(←アドレス) E abcd81(←アドレス) のように表示したいんですが、アドレスだけうまくできてHELLO WORLD のほうがうまく表示できません。 夏休みの間ブランク空けたんでポインタ全て抜けてしまったみたいです^^;  よろしくおねがいします。

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

  • ベストアンサー
  • PCFREAK
  • ベストアンサー率51% (417/805)
回答No.4

pt = &a; じゃなくて *a = *pt; が正解だと思います。 あと、printfのところも違ってますね。 正しくは、 printf("%c %x\n",*pt,&a[i]); だと思います。 一応、正解のソースコード載せておきます。 #include<stdio.h> int main(void){ int i; char *pt = "Hello World"; char a[11]; *a = *pt; for(i=0;i<=11;i++){ printf("%c %x\n",*pt,&a[i]); pt++; } return(0); }

newcolleger
質問者

お礼

なるほど、できました! 勉強しなおします。 ありがとうございました。

その他の回答 (9)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.10

あ~, 既にオフトピックですが.... char a[11]; char *p; のとき, p = a; は正しいですが p = &a; は正しくありません. a は char [11] という型を持ち char * に変換される (array-to-pointer conversion) のですが, &a は char (*)[11] という型を持っておりこれは char * と互換ではありません. たとえ値が同じであっても, 互換でない型なので a と &a を混同してはいけません. 一応 C99 では「配列がポインタに変換され*ない*場合」として次の 3つを挙げています. ・sizeof のオペランドとなるとき (配列に対しては配列全体の大きさを返す) ・単項 & のオペランドとなるとき (この場合には「配列へのポインタ」が生成される) ・配列を初期化するために使われる文字列リテラル (文字列リテラル自体は「変更できない char の配列」と定義されている). #9 で参考に挙げられているところでは, 最後のところが不明瞭ですね. 「配列を文字列リテラルで初期化するとき」に「配列をポインタに変換しない」というと, 「初期化されるべき配列がポインタに変換されない」と解釈されそうな気もしますがこっちが変換されないのは (その配列を定義しているのだから) 当然で, 「ポインタに変換されない」のは初期化する値としての文字列リテラルですから.

回答No.9

オフトピックに近いですが…… > 誤) pt = &a; > 正) pt = a; これは、a が配列である場合には、どちらも正解です。 配列名が、& のオペランドになる場合は、配列名が配列を差すポインタに読み替えられない例外3例のうちのひとつです。 つまり、前者は、「配列」a の先頭をポイントするポインタ、後者は、配列 a が、配列の先頭ポイントするポインタに読み替えられたものです。 ちなみに、配列名がポインタに読み替えられない例外のあと2つは、 ・sizeof のオペランドになる場合(sizeof a は、ポインタのサイズではなく、配列のサイズを返す) ・char型の配列を文字列リテラルで初期値するとき です。

参考URL:
http://www.kouno.jp/home/c_faq/c6.html#3
newcolleger
質問者

お礼

うーむ 奥が深いですね。 ありがとうございました。 もう少し勉強してから覚えますね^^

  • ency
  • ベストアンサー率39% (93/238)
回答No.8

No6,7 ency です。 何度もすみません。。。 以下訂正します。 > ちなみに、pt = &a; としたいのであれば、No5 ponnta さんがご指摘の > ように以下のようにすれば良いですね。 誤) pt = &a; 正) pt = a; ですね。。。 # もう、ボケボケです。。。 # この場合 a は「配列先頭要素を指すポインタ」、&a は「配列を指すポインタ」 # ですから、全然別物ですんねぇ。。。 スレ汚し、すみませんでした。。。

newcolleger
質問者

お礼

回答ありがとうございます。 pt=&a[0] pt=a は同じだと習った覚えがかすかにありますね。。 勉強不足でした。

  • ency
  • ベストアンサー率39% (93/238)
回答No.7

No6 ency です。 追加で、以下もそうですね。 5. for() 文の中の「printf("%c %x\n",pt,&a[i]); 」 ⇒以下のようにしましょう。  printf("%c %x\n",*pt,&a[i]); ちなみに、pt = &a; としたいのであれば、No5 ponnta さんがご指摘のように以下のようにすれば良いですね。 char *pt; char a[] = "Hello World"; // ポインタ pt ではなく配列 a[] を "Hello World" で初期化。 …なんだか、こう見るとすでに回答がついているものをまとめただけのような気がしてきました。。。

  • ency
  • ベストアンサー率39% (93/238)
回答No.6

気がついた部分は、こんな感じです。 1. pt = &a; の部分 ⇒ 以下のようにしましょう。  strcpy( a, pt ); この場合「#include <string.h>」もお忘れなく。 2. 配列 a のサイズは "Helo World" の文字列終端のヌル文字 '\0' 分も合わせて 12 にしましょう。 3. 表示させる for() 分の条件文は「i<=11」ではなくて「i<11」ですよね? 配列 a[] のインデックス範囲は 0~10 までです。 # ちなみに、要素数を 12 にした場合には、「i<12」ですね。 4. printf() でポインタの値を表示させる場合、%p を使うようにしましょう。 %x は整数を 16進表示させるもので、ポインタの値を表示させるものではありません。 # たいていの処理系では %p とした場合と同じ値が表示されることに # なると思いますが。。。 とりあえず、こんなところでしょうか。

  • ponnta
  • ベストアンサー率17% (31/179)
回答No.5

やりたいことを見るとこんなかんじですかね? char a[] = "Hello World"; char *pt int len /* 配列でやってみる */ len = strlen(a); for(i=0;i<len;i++) { printf("%c %p\n",a[i],(void *)&a[i]); } /* ポインタを使う */ len = strlen(a); pt = a; for(i=0;i<len;i++) { printf("%c %p\n",*pt,(void *)pt; pt++; } return(0); } PS: char a[11]に文字列を格納したいんだろうと思いますが、 文字列の最後にはNULL文字('\0')がつくので char a[12]にしましょう。 strlenを使うにはstring.hが必要です。 また、strlenの戻りに地にはNUL文字は含まれません。

  • Frey
  • ベストアンサー率60% (14/23)
回答No.3

pt = &a の段階で *pt の内容を破壊しています。 つまり、"Hello World"の上に、不特定なa[11]を上書きしています。 #include<stdio.h> int main(void){ int i; char *pt = "Hello World"; for(i=0;i<=11;i++){ printf("%c %x\n",pt,pt[i]); pt++; } return(0); } で動きませんか? 10年近く c言語をやっていないので間違えたらごめんなさい。

newcolleger
質問者

お礼

コンパイルしてみたんですが、違うみたいです^^; 勉強不足なんでもう一度勉強しなおしてみます。 ありがとうございました。

  • ymmasayan
  • ベストアンサー率30% (2593/8599)
回答No.2

char *pt = "Hello World"; char a[11]; pt = &a; これでは文字列をコピーしたことにはなりません。 ptをぶっ壊しているだけです。 つまり、Hello Worldは迷い子になっています。

newcolleger
質問者

お礼

ありがとうございました。 駄目駄目ですね。 勉強しなおします。

  • OsieteG00
  • ベストアンサー率35% (777/2173)
回答No.1

a = pt; for(i=0;i<=11;i++){ printf("%c %x\n",*pt,&a[i]); pt++; では?aは領域だけ確保されて中身がないから、ptに&a(aのアドレス)を代入しても*ptは中身がありません。

newcolleger
質問者

お礼

ポインタはむずかしいですね。。 行ったり来たりと言いますか。 もう少し勉強してみます。 ありがとうございました。