質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

3回答

1561閲覧

ポインタ

tsunpoko

総合スコア16

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2015/03/18 11:13

ある本に乗っていたソースコードです。

lang

1#include<stdio.h> 2#include<string.h> 3 4int main(){ 5 6 char str_a[20]; 7 char *pointer; 8 char *pointer2; 9 10 strcpy(str_a,"Hello, world!\n"); 11 pointer = str_a; 12 printf(pointer); 13 14 pointer2 = pointer + 2; 15 printf(pointer2); 16 strcpy(pointer2,"y you guys!\n"); 17 printf(pointer); 18}

出力結果:

![イメージ説明]WIDTH:367

最後の部分が理解できません。
strcpy(pointer2,"y you guys!\n");
printf(pointer);
この部分で、pointer2にstrcpyしているのに
printf(pointer)でなぜこのような出力になるのでしょうか。

日本語が曖昧ですが、教えていただけると助かります。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

本筋とは関係ありませんが…。
printfの第一引数として指定する文字列はフォーマットを示すためのものなので、動的に生成した文字列を指定するのは一般に不適切です。
※フォーマット文字列と他の引数との不整合や、場合によってはメモリ上のゴミ等からバグが顕在化する可能性がある
文字列sに対し、fputs(s,stdout)やputs(s) (改行付)、printf("%s",s) 等が良いです。
strcpyについては、領域溢れのチェックがないので、一般に使わない方が良い危険な関数です。
文字数の上限を定められる snprintf か、やや問題がありますが strncpy ( 文字数がぴったりの場合、明示的にNUL終端する必要がある ) あたりで。
「ポインタの挙動を見る」という目的に対しては無関係ではあるのですが、参考書のサンプルコードは、一般的に避けた方が良い書き方を注釈なしに ( 単に筆者に理解が無いだけの場合も ) していることがあります。もしもそういった書き方が普通だと思ってしまうと、後々大きな負債を抱えることになりますのでご注意を、と老婆心ながら。

投稿2015/03/21 02:01

angel_p_57

総合スコア1672

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

大体のニュアンスで回答します。

pointer・・・str_aの先頭アドレスが格納されています。str_aにはHello, world!と書かれています。
str_a[0]=H,str_a[1]=e,str_a[2]=l・・・str_a[12]=!,str_a[13]=\n

pointer2 ・・・pointer+2なので、pointerが指しているstr_aの先頭アドレス+2→str_a[2]のアドレスを指します。
そして、y you guys!を書き込むので
str_a[2]=y str_a[3]= ,str_a[4]=y・・・str_a[12]=!,str_a[13]=\nとなります

pointerはstr_aの先頭アドレスを格納しているので、Hey you guys!と表示されます

投稿2015/03/22 15:44

編集2015/03/22 17:48
jyamon3

総合スコア7

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

pointer2 = pointer + 2;

で、pointer2に(pointerの2文字目のアドレス)が入ります。
そのあとで

strcpy(pointer2,"y you guys!\n");

することで、pointer2に入っている(pointerの2文字目のアドレス)以降に、"y you guys!\n"がコピーされます。

pointerには(str_aの文字列の先頭のアドレス)が入っているので
〈str_aは配列なので、str_a自身もポインタのはずです〉

printf(pointer);

すると、str_aの内容が出力されます。

という感じだったはずです。もう、C忘れました…

投稿2015/03/18 11:23

編集2015/03/18 11:54
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2015/03/18 11:31

□□□□□□□□□□□□□□□□□□□□ ← char str_a[20]; 住所録1 ←char *pointer; 住所録2 ←char *pointer2; Hello, world!↓0□□□□□ ← strcpy(str_a,"Hello, world!\n"); str_aの0文字目の住所を記録 ← pointer = str_a; pointerの2文字目の住所=str_aの2文字目の住所を記録 ← pointer2 = pointer + 2; pointer2の先頭=pointerの2文字目=str_aの2文字目の住所以降に文字列をコピー ← strcpy(pointer2,"y you guys!\n"); Hey you guys!↓0□□□□□ ← 結果(str_aの内容) pointerの先頭=str_aの先頭から出力 ← printf(pointer); こんな感じですね。
HachiyaKouya

2015/03/18 13:03

pointer + 2 はstr_aの3文字目ですね。 C言語の配列の添字は0から始まりますので。 pointer + 0 がstr_aの先頭です。 strcopy(なんとか) はpointerが示すアドレス+2(3文字目以降)を"y you guys!\"で上書きしています。
退会済みユーザー

退会済みユーザー

2015/03/18 13:15

3文字目というと逆に分かりにくいかと。 0オリジンでは、0,1,2と数えると身に付けた方が楽です。 ですので、0文字目という表記を使っています。
退会済みユーザー

退会済みユーザー

2015/03/18 13:16

使ってなかったな… 先頭と言っている。すいません。
HachiyaKouya

2015/03/18 14:12

あ、すみません。 コメント内に「0文字目」と書いてありますね。 最初から「2文字目」と書いているので「○文字目」が「配列の○番目」という意味だと認識できませんでした。 配列としてではなく文字列として扱っているのかと思ってしまいました。 失礼しました。
tsunpoko

2015/03/19 04:54

回答ありがとうございました。 謎は解けました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問