1. ホーム
  2. arrays

[解決済み] C言語で**は何をするのですか?[重複しています]

2022-03-05 04:35:49

質問

私はjavaの知識があるC言語の初心者ですが、ポインタと配列を理解しようとしています。

私は、下付き文字 operator[] は配列定義の一部なので。

int numbers[] = {1,3,4,5};

は整数配列になり、メモリ上では4バイト×4ロットの16バイトとして表現されます。

numbers[0] = 1, address 0061FF1C
numbers[1] = 3, address 0061FF20
numbers[2] = 4, address 0061FF24
numbers[3] = 5, address 0061FF28

しかし、ポインタとなると私の知識は途切れ途切れになってしまうので、もし配列番号へのポインタを作成するとしたら、次のようにします。

int *pNumbers = &numbers[0];

というのは、次のようなものです。

そして、サイズは4バイトでしょうか?

しかし ** ポインタへのポインタは、なぜ必要なのでしょうか?私は何かを見逃しているのだと思います。 argv は型が char[ ] または char ** のようになります。

int main(int argc, char **argv){}

だから

  • これは何でしょう ( ** )?
  • どのような用途があるのでしょうか?
  • メモリ上でどのように表現されているか?

どのように解決するのですか?

C言語では、引数は値で渡されます。たとえば、main に整数値の変数があるとします。

int main( void )
{
    int x = 10;
    //...

と、次のような関数があります。

void f( int x )
{
    x = 20;
    printf( "x = %d\n", x );
} 

で、この関数をmainで呼び出すと、次のようになります。

f( x );

の値を取得し、パラメータは変数 x をmainに追加しました。しかし、パラメータ自体は引数とは異なるメモリ上の領域を占めます。そのため、関数内でパラメータを変更しても、mainの変数には影響がありません。

では、関数内でmainの変数を変更するにはどうすればよいのでしょうか。

ポインターを使用して、変数への参照を渡す必要があります。

この場合、関数宣言は次のようになります。

void f( int *px );

となり、関数定義は

void f( int *px )
{
    *px = 20;
    printf( "*px = %d\n", *px );
} 

この場合、元の変数が占有しているメモリ領域である x が変更されるのは、関数内でポインタを使用してこのエクステントにアクセスするためです。

    *px = 20;

当然ながら、この関数はmainの中で次のように呼び出されなければなりません。

f( &x );

ポインタであるパラメータ自身が px は、通常通り関数のローカル変数です。つまり、この関数はこの変数を作成し、そのアドレスを変数 x .

ここで、mainの中で、例えば次のようにポインタを宣言したとします。

int main( void )
{
   int *px = malloc( sizeof( int ) );
   //..

そして、次のように定義された関数は

void f( int *px )
{
    px = malloc( sizeof( int ) );

    printf( "px = %p\n", px );
}

パラメータとして px はローカル変数で、元のポインタに影響を与えない任意の値を代入することができます。この関数は,元のポインタが占める範囲とは異なる範囲のメモリを変更します。 px をメインで使用します。

関数内で元のポインタを変更するには? 参照渡しでいいんです!

例えば

f( &px );
//...

void f( int **px )
{
    *px = malloc( sizeof( int ) );

    printf( "*px = %p\n", *px );
}

この場合、デリファレンスを使っている関数は、元のポインタが定義されているのと同じメモリ領域にアクセスするため、元のポインタに格納されている値が関数内で変更されます。