C言語10


ししん


文字列定数とポインタ

#include <stdio.h>

int main(void)
{
    char str[] = "love";
    const char *pStr = "you";

    printf("str출력 : %s\n", str);
    printf("pStr출력 : %s\n", pStr);
}
str출력 : love
pStr출력 : you
ポインタ変数pStrは、実際の文字列定数「you」を格納しません.文字列定数は、文字列をメモリ領域に格納し、メモリアドレス値を返します.変数pStrは、実質的に文字列定数を有するアドレス値である.

ポインタ配列


ポインタ配列は、複数のポインタ変数を使用するために使用されます.
#include <stdio.h>

int main(void)
{
    char *pArr[] = {"C언어", "자바", "베이직"};
    int i;

    for(i = 0; i < 3; i++)
    {
        printf("%s\n", pArr[i]);
    }
    return 0;
}
C언어
자바
베이직

2 Dアレイ

int arr[i][j];
メモリ構造を考慮すると、i行とj列から構成されています.
#include <stdio.h>

int main(void)
{
    int i, j;
    int arr[2][3];
    arr[0][0] = 1;
    arr[0][1] = 2;
    arr[0][2] = 3;
    arr[1][0] = 4;
    arr[1][1] = 5;
    arr[1][2] = 6;

    printf("2차원 배열 값의 출력 결과 \n");
    printf("=======================\n");
    for (i = 0; i < 2; i++)
    {
        for (j = 0; j < 3; j++ )
        {
            printf("%d ", arr[i][j]);
        }
        printf("\n");
    }
    printf("=======================");
    return 0;

}
2차원 배열 값의 출력 결과 
=======================
1 2 3 
4 5 6 
=======================       

関数とポインタ


基本関数のパラメータ伝達形式は放射形式である.AからBにコピーした場合、A、Bともに値が存在します.
int main(void)
{
	int a = 10;
    temp(a);
}

void temp(b)
{
{
a:実数b:形式パラメータ、パラメータ、パラメータ

にタイルを張る


配列型の因子はポインタ型として受け入れられる.
#include <stdio.h>
void func(int *pArr);

int main(void)
{
    int arr[] = {1, 2, 3, 4, 5};
    int i;

    func(arr);
    for(i = 0; i < 5; i++)
    {
        printf("배열의 요소 출력 : %d\n",arr[i]);
    }
    return 0;
}

void func(int *pArr)
{
    int i;
    for(i = 0; i < 5; i++)
    {
        printf("배열의 요소 출력 : %d\n",*(pArr + i));
    }
    printf("\n");
}
배열의 요소 출력 : 1
배열의 요소 출력 : 2
배열의 요소 출력 : 3
배열의 요소 출력 : 4
배열의 요소 출력 : 5

배열의 요소 출력 : 1
배열의 요소 출력 : 2
배열의 요소 출력 : 3
배열의 요소 출력 : 4
배열의 요소 출력 : 5
配列をポインタとして受信して使用すると、配列のサイズがわかりませんので、パラメータに寸法を渡す必要があります.
#include <stdio.h>
int func(int *pArr, int size);

int main(void)
{
    int arr[] = {1, 2, 3, 4, 5};
    int sumArr, sizeArr;

    sizeArr = sizeof(arr) / sizeof(int);
    sumArr = func(arr, sizeArr);
    printf("배열의 총 합 : %d\n", sumArr);
    
    return 0;
}

int func(int *pArr, int size)
{
    int i, sum = 0;
    for(i = 0; i < size; i++)
    {
        sum += *(pArr + i);
    }
    return sum;
}
배열의 총 합은 : 15

値呼び出しと参照呼び出し


値を呼び出す方法(値で呼び出す)


実因数の値は形式因数で伝達され,実因数のメモリは形式因数にコピーされ,メモリは単独で管理される.
#include <stdio.h>

void callValue(int b);

int main(void)
{
    int a = 1;
    int *pa = &a;
    callValue(a);
    printf("실인수 a의 출력 : %d\n", a);
    return 0;
}

void callValue(int b)
{
    int *pb = &b;
    b = b + 3;
    printf("형식인수 b의 출력 : %d\n", b);
}
형식인수 b의 출력 : 4
실인수 a의 출력 : 1
#include <stdio.h>

void Swap(int a, int b);

int main(void)
{
    int x = 10, y = 20;
    printf("초기값 x = %d, y = %d\n", x, y);
    Swap(x, y);
    printf("함수 밖에서 변경 후 x = %d, y = %d\n", x, y);

    return 0;
}

void Swap(int a, int b)
{
    int temp;
    temp = a;
    a = b;
    b = temp;
    printf("함수 안에서 변경 후 a = %d, b = %d\n", a, b);
}
초기값 x = 10, y = 20
함수 안에서 변경 후 a = 20, b = 10
함수 밖에서 변경 후 x = 10, y = 20

リファレンス呼び出し(リファレンスによる呼び出し)


関数が呼び出されると、メモリへのアクセスに使用するアドレス値が伝達パラメータとして伝達されます.元のメモリのアドレス値で使用されるため、他の関数で値を変更すると実パラメータの値も変更されます.
#include <stdio.h>
void callReference(int *b);

int main(void)
{
    int a = 1;
    printf("a 초기값 : %d\n", a);
    callReference(&a);
    printf("실인수 a 출력 : %d\n", a);

    return 0;
}

void callReference(int *b)
{
    *b = *b + 3;
    printf("실인수 b 출력 : %d\n", *b);
}
a 초기값 : 1
실인수 b 출력 : 4
실인수 a 출력 : 4
#include <stdio.h>

void Swap(int *a, int *b);

int main(void)
{
    int x = 10, y = 20;
    printf("초기값 x = %d, y = %d\n", x, y);
    Swap(&x, &y);
    printf("함수 밖에서 변경 후 x = %d, y = %d\n", x, y);

    return 0;
}

void Swap(int *a, int *b)
{
    int temp;
    temp = *a;
    *a = *b;
    *b = temp;
    printf("함수 안에서 변경 후 a = %d, b = %d\n", *a, *b);
}
기값 x = 10, y = 20
함수 안에서 변경 후 a = 20, b = 10
함수 밖에서 변경 후 x = 20, y = 10
ユーザーから2つの数値を入力して乗算する例(リファレンス呼び出しを使用)
#include <stdio.h>
void sum_mul(int i, int j, int *hap, int *mul);

int main(void)
{
    int a,b;
    int x, y;

    printf("두개의 정수 입력 : ");
    scanf("%d%d", &a, &b);

    sum_mul(a, b, &x, &y);
    printf("두 수의 합 : %d\n", x);
    printf("두 수의 곱 : %d\n", y);
}

void sum_mul(int i, int j, int *hap, int *mul)
{
    *hap = i + j;
    *mul = i * j;    
}
개의 정수 입력 : 10 20
두 수의 합 : 30
두 수의 곱 : 200

関数ポインタ


関数は、メモリ内の場所も定義し、必要に応じて参照(呼び出し)します.関数もポインタであることがわかります.
メソッドの宣言
int (*func)(int a);
자료형(*함수 포인터 이름)(인자 목록);
#include <stdio.h>
int Add(int a, int b);
int Min(int a, int b);

int main(void)
{
    int a, b, sel, result;
    int (*fPtr)(int a, int b);

    while(1)
    {
        printf("다음 중 선택하시오 (1. 덧셈 2. 뺄셈. 3. 종료) : ");
        scanf("%d", &sel);

        switch (sel)
        {
        case 1:
            fPtr = Add;
            break;
        case 2:
            fPtr = Min;
            break;
        case 3:
            return 0;
        default:
            break;
        }

        printf("두 정수를 입력하시오 : ");
        scanf("%d %d", &a, &b);
        result = fPtr(a, b);
        printf("결과 : %d\n", result);
    }
    return 0;
}

int Add(int a, int b)
{
    return a + b;
}

int Min(int a, int b)
{
    return a - b;
}
다음 중 선택하시오 (1. 덧셈 2. 뺄셈. 3. 종료) : 1
두 정수를 입력하시오 : 3 5
결과 : 8
다음 중 선택하시오 (1. 덧셈 2. 뺄셈. 3. 종료) : 2   
두 정수를 입력하시오 : 1 5
결과 : -4
다음 중 선택하시오 (1. 덧셈 2. 뺄셈. 3. 종료) : 3

静的バインド


変数と関数は、コンパイル時にメモリのサイズと位置を決定します.

ダイナミックバインド


変数と関数は、実行時(プログラム実行時)にメモリのサイズと位置を決定します.

関数ポインタを使用する理由


たとえば、vscodeまたは이클립스では、プラグインに新しい関数が追加されるたびに、毎回再コンパイルが必要となる非効率な状況が発生し、呼び出された関数が関数ポインタを使用して動的にバインドされると、毎回コンパイルは必要ありません.
これらの例のように、関数ポインタはプログラムの拡張性と有用性に使用されます.

NULLポインタ

nullポインタは何も教えないポインタです.국룰は主に関数の動作エラーチェックに用いられる.
#include <stdio.h>
#include <string.h>

int main(void)
{
    char str[] = "Love";
    char *p;
    int a;
    p = strchr(str, 'v');
    
    if (p != NULL)
    {
        *p = 'b';
        printf("변경 결과 : %s\n", str);
    }
    else
    {
        printf("NULL을 리턴하였습니다.\n");
    }
    return 0;
}
변경 결과 : Lobe