プロが教える店舗&オフィスのセキュリティ対策術

#include <stdio.h>
#include <string.h>
int main(void)
{
char str[] = "12345""\0""67890", * p;//★ここでpを先頭のアドレスの文字コードを扱う定義にした。
//しかしなぜこのように書けたのか正直わかりません。というのもchar str[]は「文字列の文字コード」のデータを扱う
//わけじゃないですか。ってことは* p自体もアドレスではなくアドレスの「先頭の文字コード」のデータを扱うため
//これでもうまくいくのかなと自己解釈しています。

p = strchr(str, '\0');//strchrを扱う際はstrの文字列の先端のアドレスが入る。そして、アドレスを+1していき
//'\0'を見つけたら、その'\0'のアドレスをポインタpに渡す。

printf("|%s|\n", str);//文字列の最初のアドレスから'\0'となった部分までがstrにとなるので
//printfより先頭のアドレスから'\0'までの文字列が入る。そして表示される。
printf("|%s|\n", p + 1);//そのポインタpが(printfのp + 1により)+1されたことで'\0'が今現在の
//ポインタの指すアドレスとなり、そのアドレスからnullまでを表示した。

*p = '!';//そして、今現在のポインタが指すアドレスは'\0'になったアドレスであるため、 *p = '!'
//により'\0'は'!'に置き換えられた。
printf("|%s|\n", str);//そのため結果が|12345!67890|となる。
}


//以下は元のプログラムです。
/*#include <stdio.h>
#include <string.h>
int main(void)
{
char str[] = "12345""\0""67890";

char* p = strchr(str, '\0');//★strchr関数によりchar* pはポインタpとして扱われ、上と同じような処理になる
//しかしstrchr関数によりchar* pでありながらポインタのアドレス、ではなくアドレスの指す数値を扱うというのに違和感があります。
//これはstrchr関数がそういうものだからと納得するしかないのでしょうか?
printf("|%s|\n", str);
printf("|%s|\n", p + 1);

*p = '!';
printf("|%s|\n", str);
}*/

黒い星が付いている部分が自信がない疑問部分です。リファレンスを読みましたが疑問が残りました。
どうかよろしくお願いします。

A 回答 (1件)

☓ ★ここでpを先頭のアドレスの文字コードを扱う定義にした。



単にpをcharのポインタとして宣言したに過ぎません。
ここだけでは先頭のアドレスも文字コードもクソもない。
単にpと言う変数が「どんなアドレスでも代入出来る状態として」宣言されただけ、です。
余計な意味を付け加えない。

☓ ★strchr関数によりchar* pはポインタpとして扱われ、上と同じような処理になる

strchrの機能でpがポインタpになったわけじゃない。
単純に変数と代入される「値」が同じ型じゃないとダメ、なだけ。
原理的には例えば

char ch = 3;

とかやっちゃダメなのと同じ(Cだとこれが出来るから困るんだが・笑)。
左辺がchar型なのに右辺がintだと「型の不整合が起こる」。
プログラミング言語で、「静的型付け言語」(Cはこれにあたる)の場合は、変数の型と代入される「値」の間に整合性がなければならないのが原則で、これは別にCに限った話じゃない。

char* p = strchr(str, '\0');

の場合、strchrが返す値は原則「アドレス」で、左辺の変数は「アドレスを代入出来る」変数じゃないと(原則)使えない、ってぇんでpをポインタとして宣言しなければ「型の不整合」が起こる、ってだけのお話。
先に挙げた

char ch = 3;

がマズいのと理由は同じである。
難しく考えすぎ・・・。正直、ポインタに入る前のフツーの整数だとか文字の代入の辺りから勉強し直した方が良いカンジがする。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!