みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

ポインタについて

#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 のほうがうまく表示できません。
夏休みの間ブランク空けたんでポインタ全て抜けてしまったみたいです^^; 
よろしくおねがいします。

投稿日時 - 2005-09-25 19:28:55

QNo.1672825

暇なときに回答ください

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

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

投稿日時 - 2005-09-25 19:51:41

お礼

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

投稿日時 - 2005-09-25 21:54:06

ANo.4

このQ&Aは役に立ちましたか?

2人が「このQ&Aが役に立った」と投票しています

回答(10)

ANo.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 で参考に挙げられているところでは, 最後のところが不明瞭ですね. 「配列を文字列リテラルで初期化するとき」に「配列をポインタに変換しない」というと, 「初期化されるべき配列がポインタに変換されない」と解釈されそうな気もしますがこっちが変換されないのは (その配列を定義しているのだから) 当然で, 「ポインタに変換されない」のは初期化する値としての文字列リテラルですから.

投稿日時 - 2005-09-26 20:14:26

ANo.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

投稿日時 - 2005-09-26 09:04:44

お礼

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

投稿日時 - 2005-09-26 23:26:10

ANo.8

No6,7 ency です。

何度もすみません。。。
以下訂正します。

> ちなみに、pt = &a; としたいのであれば、No5 ponnta さんがご指摘の
> ように以下のようにすれば良いですね。

誤) pt = &a;
正) pt = a;

ですね。。。
# もう、ボケボケです。。。
# この場合 a は「配列先頭要素を指すポインタ」、&a は「配列を指すポインタ」
# ですから、全然別物ですんねぇ。。。

スレ汚し、すみませんでした。。。

投稿日時 - 2005-09-25 21:00:17

お礼

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

投稿日時 - 2005-09-26 15:52:29

ANo.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" で初期化。

…なんだか、こう見るとすでに回答がついているものをまとめただけのような気がしてきました。。。

投稿日時 - 2005-09-25 20:54:57

ANo.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 とした場合と同じ値が表示されることに
# なると思いますが。。。

とりあえず、こんなところでしょうか。

投稿日時 - 2005-09-25 20:47:58

ANo.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文字は含まれません。

投稿日時 - 2005-09-25 19:56:19

ANo.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言語をやっていないので間違えたらごめんなさい。

投稿日時 - 2005-09-25 19:46:30

お礼

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

投稿日時 - 2005-09-25 21:42:18

ANo.2

char *pt = "Hello World";
char a[11];
pt = &a;

これでは文字列をコピーしたことにはなりません。
ptをぶっ壊しているだけです。
つまり、Hello Worldは迷い子になっています。

投稿日時 - 2005-09-25 19:44:31

お礼

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

投稿日時 - 2005-09-25 21:54:50

ANo.1

a = pt;

for(i=0;i<=11;i++){
printf("%c %x\n",*pt,&a[i]);
pt++;


では?aは領域だけ確保されて中身がないから、ptに&a(aのアドレス)を代入しても*ptは中身がありません。

投稿日時 - 2005-09-25 19:40:37

お礼

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

投稿日時 - 2005-09-25 21:45:01