文字列とポインタに対する愛と憎しみ

文字列と文字列I / Oを表します

文字列は、ヌル文字「\ 0」で終わるchar型の配列です。文字列は、プログラミングライフで特に一般的に使用されるため、Cは文字列を処理するための多くの関数を提供します。次に、文字列I / Oについて説明します。

#include "stdio.h"
#define MSG "I am a symbolioc string constant"   //1.字符串常量
#define MAXLENGTH 81

int main(){
    
    
	char words[MAXLENGTH]="I am a string in an array";    //2.用字符数组存储
	const char *pt1="Something is pointing at me";       //3.用字符类型指针指向
	puts("Here are some strings:");
	puts(MSG);
	puts(words);
	puts(pt1);
	words[8]='p';
	puts(words);
	
	return 0; 
} 

結果は次のとおりです
ここに画像の説明を挿入
。puts()関数はprintf()関数と同じです。どちらもstdio.hヘッダーファイルで定義された入出力関数を入力しますが、puts()の違いはputs()です。関数は文字列のみを表示し、表示された文字列の最後に新しい行文字が自動的に追加されます。出力結果で確認できると思います。

プログラムで文字列を定義する

1.文字列リテラル(文字列定数)

二重引用符で囲まれた内容は、文字列リテラルと呼ばれ、文字列定数とも呼ばれます。二重引用符で囲まれた文字と、コンパイラが自動的に追加する末尾の\ 0文字は、文字列としてメモリに格納されることに注意してください。ここに注意が必要な2つの小さな詳細があります。

1.文字列リテラルの間にスペースがない場合、または空白文字で区切られている場合、Cはそれを連結された文字列リテラルとして扱います。

#include "stdio.h"
#define MSG "I am a symbolioc string constant"
#define MAXLENGTH 81

int main(){
    
    
	char words[MAXLENGTH]="I am a string in an array";   
	char word[MAXLENGTH]="I am a string"" in an"" array"; 
	printf("\nwords=");
	puts(words);
	printf("\nword=");
	puts(word);
	return 0; 
} 

2.文字列内で二重引用符を使用する場合は、二重引用符の前に円記号(\)を追加する必要があります。

	printf(" \" i love you \", he say");

結果は次のとおりです。
ここに画像の説明を挿入最後に、文字列定数は静的ストレージカテゴリに属します。つまり、関数で文字列定数を使用すると、文字は1回だけ保存され、プログラムのライフサイクル全体に存在します。関数がより頻繁に呼び出されたとしても。

2.配列とポインタ

文字列の配列形式とポインタ形式の違いは何ですか?私たちは的を射ている。

#define MSG "I am special"
#include "stdio.h"

int main(){
    
    
	
	char ar[] =MSG;
	const char *pt=MSG;
	printf("\n address of \"I am special \"   : %p","I am special");
	printf("\n                     address ar:%p",ar);
	printf("\n                     address pt:%p",pt);
	printf("\n                 address of MSG:%p",MSG);
	printf("\n address of \"I am special \"   : %p\n","I am special");
	
	return 520;
} 

出力結果は次のとおりです。
ここに画像の説明を挿入この結果から、次の結論を得ることができます。

  • ptのアドレスはMSGと同じですが、arのアドレスは異なります
  • 「Iamspecial」という文字列は、プログラムの2つのprintf関数に2回表示されますが、コンパイラは1つの格納場所のみを使用し、アドレスはMSGと同じです。
  • 静的データで使用されるメモリは、arで使用される動的メモリとは異なります。値が異なるだけでなく、特定のコンパイラは2つのタイプのメモリを表すために異なるビットを使用することさえあります

要約すると、配列を初期化すると、静的ストレージ領域の文字列が配列にコピーされ、ポインターを初期化すると、文字列のアドレスがポインターにコピーされます。

文字列のポインタ表現

ここでは、ポインタの概念を確認する場合でも、プログラミングの詳細を改善する場合でも、細部についてのみ説明します。

char *word="frame";
word[1]='l';

これは許可されていますか?私の意見では、コンパイラはこれを許可するかもしれませんが、現在のC言語標準では、そのような動作は定義されていません。たとえば、そのようなステートメントはメモリアクセスエラーを引き起こす可能性があります。

#include "stdio.h"

int main(){
    
    
	char *pl="Kinggon";
	pl[0] = 'F';     //OK?
	printf("Kinggon");
	printf(":Beware the %ss!\n","Kinggon");
	return 520; 
}

これはどのような結果につながりますか?一部のコンパイラは、各「Kinggon」を同じアドレスに置き換えることができます。出力は次の
とおりです。Finggon Finggonに注意してください!

もちろん、この理由で一部のコンパイラはとらえどころのない動作をし、他のコンパイラは異常なプログラム中断を引き起こします(これは私が実験したC-Free5コンパイラとDEV-C ++の場合です)。
ここに画像の説明を挿入したがって、推奨される使用法は次のとおりです。

const char *p1="Kinggon";

おすすめ

転載: blog.csdn.net/qq_42392049/article/details/112648892