1
 #include <stdio.h>

  int main(void){

  char *p = "Hello";  
  p = "Bye";              //Why is this valid C code? Why no derefencing operator?

  int *z;
  int x;
  *z = x
  z* = 2                 //Works
  z  = 2                 //Doesn't Work, Why does it work with characters?

 char *str[2] = {"Hello","Good Bye"};

 print("%s", str[1]);      //Prints Good-Bye.     WHY no derefrencing operator?
                          // Why is this valid C code? If I created an array with pointers
                         // shouldn't the element print the memory address and not the string?
  return 0;

  }

私の質問はコメントで概説されています。gernealでは、文字配列とポインタを理解するのに問題があります。具体的には、なぜ私は再参照解除演算子なしでそれらにアクセスできるのか。

4

5 に答える 5

2

一般的に、文字配列とポインターを理解するのに苦労しています。

これは、初心者の C プログラマーにとって非常に一般的です。私は1985年頃に同じ混乱を経験しました.

p = "Bye";

p は char* として宣言されているため、p は単に char のメモリ アドレスを含む変数です。上記の代入は、p の値を定数文字列 "Bye" の最初の文字のアドレス、つまり文字 "B" のアドレスに設定します。

z  = 2

z は char* として宣言されているため、それに割り当てることができるのは char のメモリ アドレスだけです。2 は char のアドレスではなく、定数の整数値であるため、z に 2 を割り当てることはできません。

print("%s", str[1]);

この場合、str は 2 つの char* 変数の配列として定義されます。print ステートメントでは、文字列 "Good Bye" の最初の文字のアドレスである 2 番目を出力しています。

于 2013-01-15T03:30:13.457 に答える
1

「Bye」と入力すると、実際にはString Literalと呼ばれるものが作成されます。特殊なケースですが、本質的には、そうするとき

p = "Bye";

あなたがしているのは、この文字列リテラルのアドレスpをに割り当てることです(文字列自体は、実装に依存する方法でコンパイラによって保存されます(私は思います))。Richard J. Ross III が説明しているように、技術的には char 配列の最初の要素を指定します。

特殊なケースですので、他のタイプでは動作しません。

ちなみに、 のような行に対してコンパイラの警告char *p = "Hello";が表示されるはずです。リンクで説明されているように、それらの変更は定義されていconst char *p = "Hello";ないため、定義する必要があります。


印刷コードについて。

print("%s", str[1]); 

内部的にポインター(具体的には ) を渡す必要があるため、逆参照操作は必要ありません。したがって、逆参照は によって行われます。これは、printf がポインターを想定しているときに値を渡すことでテストできます。逆参照しようとすると、ランタイム クラッシュが発生するはずです。%schar *printf

于 2013-01-15T03:25:36.077 に答える
0
 p = "Bye"; 

ポインタへのリテラルのアドレスの代入です。

array[n]

演算子は、n だけ増加したポインタ「配列」の逆参照と同様に機能します。同じではありませんが、そのように機能します。

于 2013-01-15T03:27:52.740 に答える
0

すべてがそう"Hello"ではないことを覚えておいてください。 したがって、この行は、ポインター p がie"Bye"を指していること を意味します。"Bye"char *char
p="Bye";const char *
int *
*z=2

`z` が指す `int` には値 2 が割り当てられます

while,z=2は、ポインターが がz指す同じintを指していることを意味します。しかし、は他の s を指しているわけ2ではありません。そのため、コンパイラーはエラーにフラグを立てます。2int pointerint

于 2013-01-15T03:29:32.940 に答える
-1

何かを混乱させています。整数などと同じように、文字でも機能します。

文字列は文字配列であり、配列は最初の要素のアドレスを使用してのみ変数に格納できるため、機能しないのは文字列です。

後で、文字ポインターの配列または文字列の配列を作成しました。これは、その配列の最初の要素が文字列であり、2 番目の要素も文字列であることを意味します。印刷部分に関しては、配列の 2 番目の要素を使用しています。したがって、当然のことながら、2 番目の文字列が出力されます。

このように見ると、構文が一貫していることがわかります。

于 2013-01-15T03:28:44.087 に答える