0

私は以下のプログラムを持っています

void swap(char **s1,char **s2);

int main()
{
 char *list[] = {
       "Das",
       "Kannan",
       "Rajendran",
       "Shahul"
 };   



 printf("Before swap list[0] = %s,list[1] = %s\n",*list[0],*list[1]);

 swap(&list[0],&list[1]);

 printf("After swap list[0] = %s,list[1] = %s\n",*list[0],*list[1]);

 return 0;

}

void swap(char **s1,char **s2)
{
 char *t;

 t = *s1;
 *s1 = *s2;
 *s2 = t;
}

list[0] と list[1] のアドレスを交換しようとしています。

Visual Studio 2008 は、このプログラムの実行中 (デバッグ開始中) にエラーを生成しています。発生したエラーは

ConsoleApp.exe の 0x1029984f (msvcr90d.dll) で未処理の例外: 0xC0000005: アクセス違反の読み取り場所 0x00000044。

コンパイル エラーはありません。

使用されているポインターへのポインターが正しく機能しない理由を教えてください。void swap(char *s1,char *s2) また、なぜうまくいかなかったのか知りたいです 。

4

3 に答える 3

3

Visual Studio 2008 は、このプログラムの実行 (デバッグの開始) 中にエラーを生成しています。

印刷物に欠陥があります。アスタリスクを削除します。

printf("Before swap list[0] = %s,list[1] = %s\n",list[0],list[1]);

swap(&list[0],&list[1]);

printf("After swap list[0] = %s,list[1] = %s\n",list[0],list[1]);

なんで?さて、type を持つlist[0]文字列です。それがprintfに渡したいものです。そのポインターをアスタリスクで逆参照すると、最初の文字が printf に渡されます。ここで、printf は文字列を想定しています。文字をポインターとして扱おうとすることになります。の ASCII 値は 68、つまり 16 進数で 0x44 であるため、表示されたエラー メッセージが説明されています。"Das"char *'D'char *'D''D'

void swap(char *s1,char *s2) も機能しなかった理由も知りたいです。

この関数を使用すると、2 つの文字列の文字を交換できますが、文字列自体を交換することはできません。swap 関数は、スワップされるオブジェクトへのポインターを必要とするものと考えてください。2 つの整数を交換すると、swap(int *i1, int *i2). type の 2 つの文字列を交換したいchar *場合、swap 関数には 2 つの星が必要です: swap(char **s1, char **s2)。それは理にかなっていますか?

于 2009-12-25T07:23:56.873 に答える
0

問題は printf ステートメントにあります。文字列ポインタを逆参照しています。printf を次のように変更します。

printf("Before swap list[0] = %s,list[1] = %s\n",*list[0],*list[1]);

に:

printf("Before swap list[0] = %s,list[1] = %s\n",list[0],list[1]);

(そして交換後のものも)そしてすべてがうまくいくでしょう。

于 2009-12-25T07:24:47.900 に答える
0
printf("Before swap list[0] = %s,list[1] = %s\n",*list[0],*list[1]);
swap(&list[0],&list[1]);
printf("After swap list[0] = %s,list[1] = %s\n",*list[0],*list[1]);

ここでこれらを逆参照する必要はありませんchar *。代わりに、次のことを行う必要があります。

printf("Before swap list[0] = %s,list[1] = %s\n",list[0],list[1]);
swap(&list[0],&list[1]);
printf("After swap list[0] = %s,list[1] = %s\n",list[0],list[1]);

配列には要素がlist含まれており、要素は C 文字列 (null で終了する文字列) へのポインターです。逆参照することで、実際には、文字列自体ではなく、各文字列の最初の文字を に渡します。自身がその文字値を逆参照しようとすると、メモリの無効なセグメントにアクセスしようとするため、セグメンテーション違反が発生します。char *char *printfprintf

于 2009-12-25T07:27:37.163 に答える