#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);
}*/
黒い星が付いている部分が自信がない疑問部分です。リファレンスを読みましたが疑問が残りました。
どうかよろしくお願いします。
No.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;
がマズいのと理由は同じである。
難しく考えすぎ・・・。正直、ポインタに入る前のフツーの整数だとか文字の代入の辺りから勉強し直した方が良いカンジがする。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# c言語配列の結合についてです。 なぜうまくいかないのでしょうか。 #include <stdio.h 4 2022/05/30 22:42
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# str[j++]の意味 2 2022/08/30 16:20
- C言語・C++・C# c言語でユーザ関数を利用して入力された文字列を反転させるプログラムを作りたいです。 3 2023/01/29 19:47
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- C言語・C++・C# カードシャッフルのブログラムを使ってc言語でブラックジャックをしたい 2 2022/04/12 15:13
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語のポインタに直接アドレス...
-
C言語の関数と配列に関する質問
-
fopne で失敗する原因
-
メモリのアドレスからの値の取...
-
init関数の意味
-
戻り値で構造体を返すことは可...
-
エラーの意味
-
参照型で受け取った引数をポイ...
-
【VC++2005(CLR)】マルチスレッ...
-
TCHAR文字列内の検索について
-
セグメントエラー
-
ポインタのアドレス範囲
-
【なぜポインタを使うのか】
-
C言語のプログラムをJavaに...
-
ポインタ変数の利用方法
-
コンストラクタでnewを失敗した...
-
クイックソートの比較交換回数...
-
ポインタのミスでOS壊れるの...
-
デバイスハンドルとは?
-
#define NULL ((void *)0) の弊害
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
セグメントエラー
-
C言語のポインタに直接アドレス...
-
init関数の意味
-
戻り値で構造体を返すことは可...
-
fopne で失敗する原因
-
C言語の関数と配列に関する質問
-
Run-Time Check Failure #3とい...
-
LPSTR型の初期化について
-
ExcelVBAでのkernel32(64bit)
-
main(int argc,char **argv[])...
-
アプリを32bitから64bit移行
-
ハンドルはポインタか
-
連結リスト 要素の入れ替え
-
C言語でのconstを返す関数
-
Cで作成したDLL関数をVBから呼...
-
NULLとブランクの違い
-
エラーの意味
-
ハンドル、アドレス、ポインタ...
-
DLL<->VB間での受け渡し(文字...
-
【C言語】戻り値が構造体の関数
おすすめ情報