char*he char[]の違い

3202 ワード

[C]char a[]とchar*pの違い
原文:https://blog.csdn.net/ftell/article/details/80306433
配列、文字ポインタを定義します.
char a[] = "hello";

char *p = "hello";

式char*p="hello";文字列「hello」をメモリの読み取り専用領域に配置し、pはこのメモリ領域を指すポインタであり、このメモリ領域に対する書き込み操作は不正である.この静的記憶領域は、プログラムの起動時に割り当てられ、プログラムの終了時に解放される.
式char a[]=「hello」;文字列を読み取り専用メモリ領域からスタック内に新しく開いたメモリにコピーするので、a[0]='J'に似ています.の改正は合法的です.新しくオープンしたメモリ領域全体をaと呼びます.
それらをパラメータとして関数に渡すと、両方が対等になります.

voidfoo(char* p);

voidfoo(char a[]);// exactly the same in all respects


char*はポインタを割り当て、char[]は配列を割り当てます.
char *p = "Foo";//近似等価:static const char_secret_anonymous_array[] = "Foo"; char *p = (char *) __secret_anonymous_array;
この匿名配列をポインタで変更することは許されません.そうしないと、動作は定義されていません(crashの原因になることがよくあります).ただし、配列は直接変更できます.
char a[] = "Foo";
a[1] = 'O'; // OK!

C言語におけるstrlenとsizeofの違い
sizeofとstrlenは本質的な違いがあり、sizeofはデータ型が占める空間サイズを求め、strlenは文字列の長さを求め、文字列は/0で終わる.違いは次のとおりです.
(1)sizeofはC言語の単一演算子であり、strlenは文字列の長さを計算するための関数である.
(2)sizeofはデータ型が占める空間の大きさを求め,strlenは文字列の長さを求める.
例1:
printf("char=%d/n",sizeof(char));  //1
printf("char*=%d/n",sizeof(char*)); //4
printf("int=%d/n",sizeof(int)); //4
printf("int*=%d/n",sizeof(int*)); //4
printf("long=%d/n",sizeof(long)); //4
printf("long*=%d/n",sizeof(long*)); //4
printf("double=%d/n",sizeof(double)); //8
printf("double*=%d/n",sizeof(double*)); //4

charは1バイト,intは4バイト,long点は4バイト,doubleは8バイトであることがわかる.しかしchar,int,long,doubleはいずれも4バイトの空間を占めている.
これはなぜですか.
C言語では,char,int,long,doubleといった基本データ型の長さはコンパイラ自身によって決まる.char,int,long,doubleはいずれもポインタであり,思い出すとポインタはアドレスなので,中に入っているのはアドレスであるが,アドレスの長さは現在アドレスバスの桁数で決定されており,現在のコンピュータでは32ビットのアドレスバスが一般的で,4ワードを占めている.
例2:
char a[]="hello";

char b[]={'h','e','l','l','o'};

strlen(a)、strlen(b)の値はそれぞれいくらですか?
前に分析したように、strlenは文字列の長さを求め、文字列にはデフォルトの終了子/0があり、この終了子は文字列を定義するときにシステムが自動的に加算し、配列aを定義するようにしている.配列aは文字列を定義し、配列bは文字配列を定義する.したがって、strlen(a)=5であり、strlen(b)の長さは不確定である.strlenは終了文字が見つからないからである.
以下はネット上の比較的古典的な例で、分析してみましょう.
char *c="abcdef";

char d[]="abcdef";

char e[]={'a','b','c','d','e','f'};

 

printf("%d%d/n",sizeof(c),strlen(c));

printf("%d%d/n",sizeof(d),strlen(d));

 

printf("%d%d/n",sizeof(e),strlen(e));

出力の結果は次のとおりです.
4 6
7 6
6 14
分析してみます.
第1行はcを1つの文字ポインタ変数として定義し、定数文字列を指し、cには文字列のヘッダアドレスが格納されている.
2行目はdを1つの文字配列として定義し、この文字配列に文字列として値を付与する.
3行目で定義されるのも文字配列で、単一の要素として値を割り当てます.
文字列で値を割り当てると、abcdef、末尾に自動的に「/0」が加算.
strlen(c)は/0に出会うと終わり、文字列の長さを6と求めます.
sizeof(c)はタイプ空間サイズを求め,前述したようにポインタ型の点の空間サイズが4バイト,システムアドレスバス長が32ビットの場合である.
strlen(d)も同様で、文字列は値を割り当てて、自動的に/0を追加して、文字列の長さを求めるのは当然6です.
sizeof(d)は、この配列が占める空間の大きさ、すなわち配列が占めるメモリ空間のバイト数を求めるものであり、7であるべきである.
sizeof(e)は、配列eが単一の要素で付与され、/0終端子がないため、占有空間の大きさは6バイトである.
strlen(e)は、/0の末尾の文字列の長さを探しますが、/0が見つからないため、返される値は不確定な値です.