C言語の基礎 (文字列の扱いとポインタ) NO.9 備忘録

c言語の文字列はchar型文字列の連なりで、先頭文字のアドレスとNULL文字('¥0')による終端で定義される。
先頭文字から順番に文字がメモリに埋められていて、('¥0')が見つかった時点で文字列の最後という定義になっている、

文字列を直接表す書き方として、"で文字列を囲む、__文字列リテラル__という書き方がある。

"123"と書けば、これが文字列リテラルである。

__文字列変数の定義__
1.配列を使った方法 (2パターン)
`char acData_a[] = "abc";`
`char acData_b[] = { 'a','b','c',NULL };`

```c++:test.cpp
  char acData_a[] = "abc";
  
  char acData_b[] = { 'a','b','c',NULL };
  

  CCLOG("acData_aのサイズ:%d",(int)sizeof(acData_a));
  CCLOG("acData_bのサイズ:%d",(int)sizeof(acData_b));
  
  for ( int i = 0; i<sizeof(acData_a); i++ )
  {
    CCLOG("acData_a[%d]の値:%c アドレス:%p",i,acData_a[i],&acData_a[i]);
  }

  for ( int i = 0; i<sizeof(acData_b); i++ )
  {
    CCLOG("acData_b[%d]の値:%c アドレス:%p",i,acData_b[i],&acData_b[i]);
  }
```
実行結果
cocos2d: acData_aのサイズ:4
cocos2d: acData_bのサイズ:4
cocos2d: acData_a[0]の値:a アドレス:0x7fff5ccc6d7c
cocos2d: acData_a[1]の値:b アドレス:0x7fff5ccc6d7d
cocos2d: acData_a[2]の値:c アドレス:0x7fff5ccc6d7e
cocos2d: acData_a[3]の値:
cocos2d: acData_b[0]の値:a アドレス:0x7fff5ccc6d78
cocos2d: acData_b[1]の値:b アドレス:0x7fff5ccc6d79
cocos2d: acData_b[2]の値:c アドレス:0x7fff5ccc6d7a
cocos2d: acData_b[3]の値:

・配列の中にはそれぞれchar型のデータ'a','b','c','d','¥0'が入っている。
・1文字ずつアドレスが増えているのが確認できる。
・アドレスの表記方法
※ __(acData_a+0)__ or   __&acData_a[0]__
 
・値の表記方法
※ __(acData_a[0])__ or   __*(acData_a+0)__


__文字列をダブルクォーテーションで囲った文字列リテラルは末尾にNULLを加えたデータを表す__

2.ポインタを使った方法
`char *pcData = "abc";`

__例__

```c++:test.cpp
  char *pcData = "abc";
  
  CCLOG("size:%d", (int)sizeof(pcData));
  
  CCLOG("pcData+0のアドレス:%p 値:%c",pcData+0,*(pcData+0));
  CCLOG("pcData+1のアドレス:%p 値:%c",pcData+1,*(pcData+1));
  CCLOG("pcData+2のアドレス:%p 値:%c",pcData+2,*(pcData+2));
  CCLOG("pcData+3のアドレス:%p 値:0x%02x",pcData+3,*(pcData+3));
```
実行結果
cocos2d: size:8
cocos2d: pcData+0のアドレス:0x10c3618c0 値:a
cocos2d: pcData+1のアドレス:0x10c3618c1 値:b
cocos2d: pcData+2のアドレス:0x10c3618c2 値:c
cocos2d: pcData+3のアドレス:0x10c3618c3 値:0x00

"abc"という文字列は最後にNULL文字を持った全体で4バイトのデータを表す。


#疑問点
`char *pcData = "abc";`
`CCLOG("size:%d", (int)sizeof(pcData));`

__なぜこれが8なんだろう。。__

  
  
`char acData[] = "abc";`
`char *pcData = (char*)"abc";`

この場合のacDataとpcDataは共に__char型のポインタ変数__                                                                                                                                                                                                                                                                                                                                                                                                                                 である。

#文字列定数
`char *acData = "abc";`
後から値を変更しようとするとエラーになり異常終了する。
↓
`const char acData[] = "abc";`
__const__という定数を表すキーワードをつけておくと、コンパイル時にエラーメッセージが表示される。

#文字列表記
```c++:test.cpp
  char test1[] = "a";
  
  char *test2 = (char*)"abc";
  
  CCLOG("%s",test1);
  CCLOG("%s",test2);
  CCLOG("%c",*(test2+0));
  CCLOG("%c",*(test2+1));
  CCLOG("%c",*(test2+2));
```
実行結果
cocos2d: a
cocos2d: abc
cocos2d: a
cocos2d: b
cocos2d: c

```c++:test.cpp
  char *szData = (char*)"Hello,world";
  
  printf("%s\n",szData);
  printf("%s\n",szData+6);
  
  CCLOG("%s",szData);
  CCLOG("%c",*(szData+6));
```
実行結果
Hello,world
world
cocos2d: Hello,world
cocos2d: w

char型のポインタを渡すと、そこからNULL文字までの文字を表示してくれるので、末尾の"world"を表示したい場合は[w]のアドレスを渡せばいい。
[w]の文字は先頭から７文字目なのでszDataに6を足せばwのアドレスになる。