【C言語】
ポインタが分からない
*と&の使い方は8種類だけ

ポインタが 分からない

warning: parameter ‘p’ set but not used

警告:引数 ‘p’ が上書き後未使用
[-Wunused-but-set-parameter]


■ポインタ*と&の使い方は8種類だけ

#include <stdio.h>
int main(void){
    int     VX;
    int     VY;
    int     *PX;
    int     *PY;
    //整数型変数に代入できるのは以下2種類のみ
    VX=1234;    //整数型定数
    VY=VX;      //整数型変数
    printf("変数の値=%d\n",VY);
    //ポインタ型変数に代入できるのは以下3種類のみ
    PX = NULL;  //NULLポインタ
    PX = &VX;   //変数のアドレス
    PY = PX;    //ポインタ型変数
    printf("変数のアドレス=%p\n",PY);
    //ポインタの指す先に代入できるのは以下3種類のみ
    *PX = 4321 ;//整数型定数
    *PX = VY ;  //整数型変数
    *PY = *PX ; //ポインタの指す先の整数型
    printf("ポインタの指す先=%d\n",*PY);
}

ポインタが分からない人は、
上記コードの2+3+3=8種類の
使い方をマスタして下さい。

初心者がマスタすべき*と&の組み合わせは
この8種類しかありません。


■引数更新しても呼び元変わらず(整数版)

#include <stdio.h>
void 時給更新要求(
    int 時給コピー
) 
{
    時給コピー = 2000 ;//コピーを変更しても原本は変わらない
}
int main(void) {
    int 時給原本 = 1000 ;       //1000円

    printf("%d円\n",時給原本);  //1000円   
    時給更新要求(時給原本);     //更新されない    
    printf("%d円\n",時給原本);  //1000円のまま      
}

時給原本の値を1000円から2000円に変更したいのですが
更新されません。

C言語は Call by Value なので
呼び先の関数引数を更新しても、
呼び元の関数引数は更新されません。

つまり、
呼び先 時給更新要求()の引数「時給コピー」を更新しても
呼び元 main() 関数の引数「 時給原本」は更新されません。 


➡ポインタを使って修正

#include <stdio.h>
void 時給更新要求(
    int *時給原本保管場所
) 
{
    *時給原本保管場所 = 2000 ;  //時給原本保管場所には時給原本がある
}
int main(void) {
    int 時給原本 = 1000 ;       //1000円
    
    printf("%d円\n",時給原本);  //1000円
    時給更新要求(&時給原本);     //時給原本の保管場所    
    printf("%d円\n",時給原本);  //2000円になる      
}

■引数更新しても呼び元変わらず(ポインタ版)

#include <stdio.h>
void    別の文字列を指したい(
    char *ポインタ変数のコピー
) {
    ポインタ変数のコピー = "コピーを変更しても呼び元は変わらない";
}
int main(void) {
    char    *ポインタ変数 = "ポインタが分らない";
    
    printf("%s\n",ポインタ変数);
    別の文字列を指したい(ポインタ変数);       
    printf("%s\n",ポインタ変数);  //「ポインタが分からない」まま
}

➡ポインタのポインタを使って修正

#include <stdio.h>
void    別の文字列を指したい(
    char **ポインタ変数のアドレス
){
    *ポインタ変数のアドレス = "ポインタが分かった";
}
int main(void) {
    char    *ポインタ変数 = "ポインタが分らない";
    
    printf("%s\n",ポインタ変数);
    別の文字列を指したい(&ポインタ変数);       
    printf("%s\n",ポインタ変数);  //「ポインタが分かった」!!
}

呼び元がポインタの場合も同様に
関数引数を
ポインタ(*)から
ポインタポインタ(**)に変更して
ポインタポインタの指す先を更新します。

参考:

CFAQ-4.8: 呼んだ側のポインターの値は変わらなかった。

http://www.kouno.jp/home/c_faq/c4.html#8

MSC13-C. 使用されない値を検出して削除する

https://www.jpcert.or.jp/sc-rules/c-msc13-c.html