61822


教えていただけると幸いです。

[code]

    #include <stdio.h>
    #include <string.h>
    
    void funcDouble(int *ptX) {
        *ptX = *ptX * 2;
        return 0;
    
    }
    
    int main(void) {
        int a = 3;
        printf("変数aの値は%dです\n", a);
    
        printf("funcDouble関数により、変数aを２倍にします\n");
        funcDouble(&a);
    
        printf("変数aの値は%dです\n", a);
    
        return 0;
    }
    
[/code]


CC BY-SA 4.0
2019-12-26T10:21:54.130
61811
2019-12-27T04:07:41.640
2019-12-26T11:35:41.373
19110
34680
question
c
ポインタについてですが(&a)の&がつく意味が分かりません


おそらくこんなことでしょうか。

関連するこれらの記事を参照してみてください。ポイントを抜粋します。  
[プログラミング言語2 - 4. アドレスとポインタ](http://flute.u-shizuoka-ken.ac.jp/%7Es-
okubo/class/language/004.htm)

> 4.1 メモリとアドレス  
>  4.2 アドレスの参照  
>
> C言語では、変数に値を保存することができます。たとえば、整数型（int型）の変数ならば整数を保存することができるし、文字型（char）型の変数なら文字を保存することができます  
>  これらの変数ですが、計算機の中では、当然、メモリ上に保存されます。 メモリ上のどこに保存されるのかは、OSやコンパイラが、適時行ってくれます。
>
>   * 『変数の前に & をつけると、その値をどこに保存しているか（アドレス）を参照できる』
>   * 『アドレスの前に * をつけると、そのアドレスに保存している値を参照できる』
>

>
> 4.3 ポインタとアドレス

[プログラミング言語2 - 8. 関数の自作の基礎](http://flute.u-shizuoka-ken.ac.jp/%7Es-
okubo/class/language/007.htm)

> 8.3 関数の引数  
>  関数の引数には、
>
>   * 値渡し
>   * アドレス渡し
>

>
> の2通りがあります。ここでは、その内容と違いについて説明します。
>
> 8.3.2 アドレス渡し  
>  関数の引数として、（変数の）アドレスを渡す方法です。
>
> 関数に渡されるのは、『変数のアドレス』です。 関数内部では、自分で使用する変数のアドレスを、引数として渡されたアドレスに設定します。
> つまり、関数内部と外部で名前は異なる変数かもしれませんが、保存する場所は一緒になります。

* * *

質問記事の`void funcDouble(int *ptX)`の関数は、パラメータにint型変数へのポインタ(アドレス)を渡す必要があります。

しかし、呼び出し元の`int main(void)`関数の中で、`a`という変数は`int a =
3;`と定義されていて、int型変数そのものであり、ポインタ(アドレス)ではありません。

そこで変数`a`のアドレス値を表すために`a`の前に`&`を付けて、`(&a)`としているわけです。

ここで、`&`を付けずに`funcDouble(a);`としてコーディングすると、パラメータの型が関数宣言と違うということでコンパイル時に(オプション指定によりますが)警告またはエラーになるはずです。  
警告ならコンパイル出来るかもしれませんが、動作させると想定した結果にならなかったり、segmentation faultとかaccess
violationとかのエラー/例外になったりします。

あるいは`a`がint型変数ではなくint型変数へのポインタ変数であれば、`&`を付けずに指定できます。(むしろ付けると問題になる)  
以下のような感じですね。

[code]

    int main(void) {
        int data = 3;
        int *a = &data;
        printf("変数aの値は%pです\n", a);
        printf("変数dataの値は%dです\n", data);
        
        printf("funcDouble関数により、変数aの指す先の変数dataを２倍にします\n");
        funcDouble(a);
        
        printf("変数aの指す先の変数dataの値は%dです\n", *a);
        
        return 0;
    }
    
[/code]


CC BY-SA 4.0
2019-12-27T02:48:55.830
61819
2019-12-27T02:48:55.830
2020-06-17T08:14:45.997
-1
26370
61811
answer


直接の回答ではないのですが、C言語のポインタは表記の問題で混乱する人が多いと思います。  
質問者もこの点が理解の妨げになっているかもしれないので
[苦しんで覚えるC言語](https://9cguide.appspot.com/15-05.html) の解説を引用しておきます。

> *の記号は、実に3通りの意味を持っており、混乱の原因になります。
>
> (略）
>
> 2つ目は、間接参照演算子です。ポインタ変数を通常変数モードにします。 式の中で使用する記号で、*p のようにして使用します。  
>  ポインタ変数モードの時のポインタ変数では掛け算が出来ないため、 乗算演算子と同じ記号を使っていても区別が付きます。
>
> 3つ目は、ポインタ変数を宣言する時に使用する記号です。 宣言の時にのみ使用され、int _p のようにして使用します。  
>  ここがややこしいのですが、通常変数モードに切り替える間接参照演算子_と、 宣言の時に使用する*の記号は、何の関係もない全く別の記号です。  
>  たまたま同じ文字を使っているだけのことに過ぎません。


CC BY-SA 4.0
2019-12-27T04:07:41.640
61822
2019-12-27T04:07:41.640
2020-06-17T08:14:45.997
-1
3271
61811
answer