C言語9


ししん


特定のメモリアドレスを格納する変数
メモリは、アドレスからメモリにアクセスし、値を読み取り、書き込むことができます.ポインタはメモリアドレス値を指す変数です.
その利点は,より重いデータを処理する際に,アドレス値で参照する方法がデータをインポートするよりも有効であることである.

ポインタ宣言

char *pA;
int *pB;
double *C;
ポインタ変数宣言時に、変数名の前に*符号を付けます.
int b = 100;
int *pB = &b;
変数のアドレス値は、&によって得ることができる.
#include <stdio.h>

int main(void)
{
    int b = 100;
    int *pB = &b;
    
    printf("b = %d\n", b);
    printf("&b = %d\n", &b);
    printf("*pB = %d\n", *pB);
    printf("pB = %d\n", pB);
}
b = 100
&b = 1862201964
*pB = 100
pB = 1862201964
なお、ポインタ変数宣言時の*符号と出力時の*値は異なる機能である.

ポインタ演算

  • ポインタ間で加算できません.
  • ポインタ間の減算値は、2つの要素間の相対距離です.(でもあまり意味がない…)
  • ポインタに整数を減算できます。


    基準ポインタ位置から移動するアドレスの位置を示します.
    #include <stdio.h>
    
    int main(void)
    {
        char str[] = "Programming";
        char *ptr1;
    
        ptr1 = &str[0];
    
        printf("%x\n", ptr1);
        printf("%x\n", ptr1 + 1);
        printf("%c\n", *(ptr1 + 1));
        printf("%x\n", ptr1 + 3);
        printf("%c\n", *(ptr1 + 3));
    }
    6b3fb258
    6b3fb259
    r
    6b3fb25b
    g
    ダイレクトアクセス
  • アレイ:ダイレクトアクセス
  • ポインタによるアクセス:間接アクセス
  • 奇数を持つ配列の中間値をポインタで出力する例
    #include <stdio.h>
    
    int main(void)
    {
        int arr[5] = {1, 2, 3, 4, 5};
        int *ptr = &arr[0];
        int len_arr = sizeof(arr) / sizeof(int);
    
    	printf("%d\n", *ptr + (len_arr / 2));
    }
    ポインタアドレス値の後に演算される数値単位は、byteではなく、요소である.
    たとえば、文字列は1 byte、整数配列は4 byteです.

    ポインタのデータ型

    #include <stdio.h>
    
    int main(void)
    {
        char a = 'A';
        char *pA = &a;
        
        int b = 100;
        int *pB = &b;
        
        double c = 3.14;
        double *pC = &c;
    
        printf("pA의 크기 : %dbyte\n", sizeof(pA));
        printf("pB의 크기 : %dbyte\n", sizeof(pB));
        printf("pC의 크기 : %dbyte\n", sizeof(pC));
        printf("*pA의 크기 : %dbyte\n", sizeof(*pA));
        printf("*pB의 크기 : %dbyte\n", sizeof(*pB));
        printf("*pC의 크기 : %dbyte\n", sizeof(*pC));
    }
    pA의 크기 : 8byte
    pB의 크기 : 8byte
    pC의 크기 : 8byte
    *pA의 크기 : 1byte
    *pB의 크기 : 4byte
    *pC의 크기 : 8byte
    記憶領域が同じポインタ変数にデータ型を分割するのは、各ポインタ変数が指す変数の実際の値を参照するためである.

    ダイナミックメモリ


    ダイナミックメモリを割り当てる理由


    メモリ割り当てはコンパイル時に完了します.メモリを動的に割り当てて、固定フローのデータフォーマットではなく、実行時に決定します.

    ダイナミックメモリの割り当てと無効化


    ダイナミックメモリ割り当て関数のプロトタイプ

    void malloc(size_t size);
    伝達パラメータsizeはバイト単位で入力され、メモリ割り当てが完了するとメモリのアドレス値が返されます.メモリ不足の場合はnullを返します.戻りタイプはvoidで、指定されたタイプのポインタが返されません.(必要に応じて任意のサイズのメモリを割り当て、必要に応じてメモリを使用)

    ダイナミックメモリ解放関数のプロトタイプ

    void free(void* memblock);
    メモリの使用後は解放し、転送パラメータを使用してメモリへのポインタを挿入する必要があります.解放しないとメモリの漏洩が発生します.
    #include <stdio.h>
    #include <stdlib.h>
    
    int main(void)
    {
        int num;
        int *student;
    
        printf("학생 수를 입력하세요 : ");
        scanf("%d", &num);
    
        student = (int*)malloc(sizeof(int) * num); // 할당한 메모리를 int형으로 형변환
    
     	// 동적 메모리 할당 뒤 국룰
        if(student == NULL) // null 포인터 검사
            {
                printf("메모리가 부족하여 메모리를 할당할 수 없습니다.\n");
                return 0;
            }
        //
    
            printf("할당된 메모리의 크기는 %d 입니다.\n", sizeof(int) * num);
    
            free(student);
    
            return 0;
    }

    メモリ再割り当て


    リアルタイムメモリが割り当てられていても、使用中にメモリサイズを増やす必要がある場合があります.malloc関数で割り当てられたメモリを動的に再割り当てできます.
    void = remalloc(void* memblock, size_t size);
    既存のすべてのダイナミックメモリの値を持つダイナミックメモリを作成しますが、サイズのみが変更されます.既存のメモリと新しい拡張メモリを含むサイズに設定します.
    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
        int i;
        int *arr = (int*)malloc(sizeof(int) * 5);
        int *rearr;
    
        for(i = 0; i < 5; i++)
        {
            arr[i] = i + 1;
        }
        rearr = (int*)realloc(arr, sizeof(int) * 10);
        for (i = 5; i < 10; i++)
        {
            rearr[i] = i + 1;
        }
        for (i = 0; i < 10; i++)
        {
            printf("%d\n", rearr[i]);
        }
    
        free(rearr);
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10