###概要
C言語の文字列変数のchar*
とchar[]
の違いを検証したので、その結果をメモとして残します。
検証結果についてはメモとして残しているだけなので#include <stdio.h>
などは省略し、要点のみを記載します。
###環境
- Windows 10 Home
- gcc (MinGW.org GCC-6.3.0-1) 6.3.0
###検証結果
char*
で宣言された変数に代入されるのは定数領域上の"name"文字列の先頭アドレスです。
char[]
で宣言された変数に代入されるのはスタック領域上にコピーされた文字列の先頭アドレスです。
修正
char[]`で宣言された変数に代入されるのは定数領域上の文字列からコピーされた{'n', 'a', 'm', 'e', '\0'}です。
@fujitanozomuさん、ご指摘ありがとうございます。
char *literal = "name"; // 定数領域上に生成された"name"文字列の先頭アドレスを代入
char stack[] = "name"; // スタック領域にコピーされた"name"文字列を代入
変数の配置されたアドレスを表示させると、配置されているアドレスがそれぞれ異なることが分かります。
char stack[] = "foo";
char _stack[] = "bar";
char* literal = "foo";
char* _literal = "bar";
printf("%p\n", stack);
printf("%p\n", _stack);
printf("%p\n", literal);
printf("%p\n", _literal);
char*
型で宣言された変数には下記の性質があることが確認出来ました。
- ポインタの保持しているアドレスを操作できる。
- 文字列に対する操作は不可。
char *literal = "name";
++literal; // インクリメントされたポインタは先頭アドレスの次(a)の値をさす
--literal; // ポインタの保持しているアドレスを先頭(n)に戻す
// ++(*literal); // 定数領域の文字列に対してインクリメントを行うため、実行時エラー
char[]
型で宣言された変数には下記の性質があることが確認出来ました。
- ポインタの保持しているアドレスを操作できない。
- 文字列に対する操作は可能。
char stack[] = "name";
// ++stack; // 配列に対してインクリメントは不可
++(*stack); // 向き先の値に対して操作可
またどちらで宣言されていても読み取りは出来ます。
char *literal = "name";
char stack[] = "name";
printf("%c\n", literal[1]);
printf("%c\n", stack[1]);
printf("%c\n", *literal + 1);
printf("%c\n", *stack + 1);