• ベストアンサー

ポインタについて

#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
質問者

お礼

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

関連するQ&A

  • ポインタについて

    今初めてポインタというものを勉強しております。 よろしくお願いします。 ◎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も同じような事だとは思いますが違いを教えていただけると嬉しいです。 よろしくお願いします。

  •  現在、私はC言語を学んでいます。

     現在、私はC言語を学んでいます。  プログラミングの初期の初期の問題なんですが、 「Hello World」という有名なプログラムがありますよね? それについての質問です。 #include<stdio.h> main() { printf("Hello World"); return 0; } も #include<stdio.h> main(void) { printf("Hello World"); return 0; } も #include<stdio.h> int main() { printf("Hello World"); } もちゃんと表示できます。 ここで質問です。 int main(void) int main() main() main(void) はどう違うんですか? あと、 return 0; はあっても無くてもいいようなんですが どういう意味があるんでしょうか?

  • ポインタ

    #include<stdio.h> int main() { char *p; p="ポインタ"; printf(p); return 0; } なぜ p="ポインタ"; とできるのですか? 普通は  int *i, j; i=&j; *i=100; こんな感じでやるのでは?

  • ポインタ配列のアドレスについて

    #include <stdio.h> int main() { int i; char *ary[] = { "a" , "b" , "c" }; for(i=0; i<3; i++) printf("%u\n" , &ary[i]); return 0; } /*実行結果 6618616 6618620 6618624 */ 上記のプログラムを実行したときポインタ配列*aryがchar型だろうがdouble型だろうがアドレスが4つとびになるのですがなぜなんでしょう?アドレスを求めるプログラム自体が間違っているのでしょうか?

  • ポインタにによる値の表現と文字列の表現について

    ◎1------------------------------ #include<stdio.h> int main(void) { char *pt="ABC"; printf("pt=%s\n",pt); char dt[10]="ABCDE"; char *pp; pp=dt; printf("pp=%s\n",pp); return 0; } -------------------------------------- ◎2---------------------------------- #include<stdio.h> int main(void) { char *pt="ABC"; printf("*pt=%s\n",*pt); char dt[10]="ABCDE"; char *pp; pp=dt; printf("*pp=%s\n",*pp); return 0; } ----------------------------------- ◎3--------------------------------------- #include<stdio.h> int main(void) { int ary[5]={111,222,333,444,-1}; int* pt=ary; while(1){ printf("%d ",*pt); ++pt; if(*pt==-1){ break; } } puts(""); return 0; } ----------------------------------------------- 以上3つのプログラムで、◎1はprintfで「*」が付いてなく、正常に実行出来ました。 ◎2はprintfで「*」が付いてなく、エラーは出ませんが、文字列が表示されませんでした。 ◎3は文字列ではなく値ですが、printfで「*」が付いていて正常に実行できます。 これは、値の場合は「*pt」とすることで、ptのアドレスに値を代入しているという事で、「printf("%d ",*pt);」で実行できたということですかね? 文字列の場合は、先頭のアドレスを渡すだけなので、「printf("pt=%s\n",pt);」のようにしてアドレスを参照しないとダメであるということですか? ◎2で「printf("*pt=%s\n",*pt);」としてしまうと、何が起きてしまうのかわかりません。 以上、教えていただけると嬉しいです。

  • C言語プログラミングについて

    #include <stdio.h> int main(void) { printf("hello,world\n"); } □■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■ #include <stdio.h> int main(void) { printf("hello"); printf(",world"); printf("\n"); } 上の2つのプログラムをコンパイルするとどのような違いが生じるんですか??printfってどんな働きをするんですか?

  • ポインタ勉強中です。しかも実行するとおかしいです。

    <本に載ってたソース> #include<stdio.h> #include<string.h> int main() { char msg[20]; char *str=NULL; int i; int cnt; str=&msg[0]; printf("文字を入力してください"); scanf("%s",&str); cnt=strlen(msg); str=msg+cnt; for(i=cnt;i>=0;i--){ printf("%c",*(str--)); } printf("\n"); return 0; } char *str=NULL;は、ポインタstrを空にするということでしょうか? いつもながらstrlenとsizeofが混じります。 sizeofがバイトの大きさで、strlenが、文字数でしたっけ?

  • ポインタに ~0を入れること

    見かけたCのプログラムで、 ポインタに~0を代入するものを見ました。 そのプログラムをそのまま載せるのはわかりにくいので、 代わりに以下のプログラムを作って実行しました。 #include <stdio.h> int main(void) { char *pa[3]; int i; pa[0]=0; pa[1]=~0; pa[2]="Hello"; printf("sizeof(char*)=%d\n", sizeof(char*)); for(i=0; i<=2; i++) { if(pa[i]==NULL) printf("pa[%d] はNULLです。\n", i); if(pa[i]==(char*)0xFFFFFFFF) printf("pa[%d]は全ビット1です。\n", i); if(pa[i]==~0) printf("pa[%d]は~0です。\n", i); } return 0; } 結果 sizeof(char*)=4 pa[0] はNULLです。 pa[1]は全ビット1です。 pa[1]は~0です。 このプログラムはコンパイル時にエラーも警告も出ず、 動作も意図したとおりです。 pa[1]に入っている ~0 は、int型の定数なのでしょうか。 それならば、 pa[1]=~0; という代入や if(pa[i]==~0) という比較は 左辺はchar*型で右辺はconst int型であって型が異なりますが、 問題ないのでしょうか。 ~0は0の否定なので、全ビットは1なのでしょうけど、 int型(の定数)だと思います。 ~0というのは何か特別な値なのでしょうか。 ポインタに~0を入れるというのは、意味があるのでしょうか。 (例えば、「ポインタに0を入れるということは、ヌルポインタであって、ポインタとして無効なんですよ」のようなこと。)

  • 改行について 1行に何個かづつ表示するとき

    よく画面に回数を入力した分だけhello!worldと表示しましょうとありますよね? そのプログラミングはこうなると思うのですが #include<stdio.h> main() { int i,a; printf("回数を入力 → "); scanf("%d",&a); for(i=1;i<=a;i++){ printf(" hello! world "); } }  改行をする場合worldのあとに\nをいれますよね。では例えば 10回表示して1行に3個づつ表示する場合はどうしたらいいですか。 考えてみたのはif(a%3==0) printf("/n");か、if(a<=3) printf("\n"); の2つが思い浮かびました。上の画面のprintf命令のあとに入れてみましたが うまくいきません。こんなことを気にしないほうがいいのかもしれませんが 気になります。どこが間違っているのでしょうか。位置ですか。それとも 2つの案がはじめから違いますか。

  • str[101]までしかないのに???

    #include<stdio.h> int main(void){ int str[101]; int *pt,i,a,count=0; pt=str; *pt=0; for(i=0;i<101;i++){ a=*pt+i; pt++; *pt=a; printf("%5d",*pt); count++; if(0==(count%10)){ putchar('\n'); } } return 0; } の答えが 0 1 3 6 10 15 21 28 36 45 55 66 78 91 105 120 136 153 171 190 210 231 253 276 300 325 351 378 406 435 465 496 528 561 595 630 666 703 741 780 820 861 903 946 990 1035 1081 1128 1176 1225 1275 1326 1378 1431 1485 1540 1596 1653 1711 1770 1830 1891 1953 2016 2080 2145 2211 2278 2346 2415 2485 2556 2628 2701 2775 2850 2926 3003 3081 3160 3240 3321 3403 3486 3570 3655 3741 3828 3916 4005 4095 4186 4278 4371 4465 4560 4656 4753 4851 4950 5050 なんですが、str[101]までしかないのに最後の5050はstr[102]なので表示されないと思うんですが、何故表示されるのか分かりません。お願いします(_ _)

専門家に質問してみよう