블로그 이미지
하루, 글. 그림. 영상매체. 표현을 도와주는 기기들. 도전 중. 동화다아아
    동화다아아

    카테고리

    분류 전체보기 (176)
    잡담 (1)
    IT 기기-리뷰&뉴스 (7)
    리뷰 - 도서 (1)
    리뷰 - 영상 (0)
    리뷰 - 그림/음악 (1)
    내장형 하드웨어 (163)
    Total
    Today
    Yesterday
     

    함수 포인터

    ⇒ 변수나 파일을 포인터 변수를 이용하여 접근하듯이, 함수도 포인터를 이용하여 호출할 수 있다. 즉, 함수포인터는 함수의 위치를 가리키는 포인터.

    ⇒ 함수 포인터(function pointer)는 함수의 실행코드의 시작주소를 가지고 있으며, 함수 포인터를 이용하여 함수를 호출할 수 있다.

    ⇒ C 언어의 경우 함수자체를 변수로 만들 수는 없다. 대신 함수를 포인트 하는 것은 가능한데, 이것을 통해서 함수를 포인터처럼 사용할 수 있으며, 이 포인터가 가리키고 있는 곳의 함수를 실행시킬 수도 있다.


    ⇒ 배열이름이 메모리 주소값을 가지는 상수이듯이, 함수 이름도 함수의 시작코드의 주소값을 가지는 주소값 상수로 볼 수 있다. 함수 포인터 변수의 선언 형식은 다음과 같다.


            반환자료형(* 함수 포인터 변수 이름) (인수1, 인수2, …, 인수n);


    ⇒ 1. 타입, 2. 이름 대신 (*), 3. ( )

     

     void test1()

     {

            printf("test1");

     }

     void (*) ( );

      

     void (*name) ( );

     int *P;

    name

    4byte


    P

    4byte

     



    // 함수 포인터의 사용 예제

    #include<stdio.h>

    int plus(int, int); // → int (*) (int, int);

    int minus(int, int); // → int (*) (int, int);

    int main()

    {

            char op;

            int num1;

            int num2;

            int (*handler) (int, int); // 함수 포인터의 선언 → int (*) (int, int);

            printf("Please Enter operator <'+' or '-'> : ");

            scanf("%c",&op);

            if(op=='+')

            {

                    handler = plus;

            }

            if(op=='-')

            {

                    handler = minus;

            }


            printf("Enter the first operand: ");

            scanf("%d", &num1);

            printf("Enter the second operand: ");

            scanf("%d", &num2);

            printf("the result is %d.\n",(*handler) (num1,num2));

                                            // = handler(num1,num2);


            return 0;

    }

    int plus(int a, int b)

    {

            return (a+b);

    }

    int minus(int a, int b)

    {

            return (a-b);

    }

    ⇒ 실행결과

            


    ⇒ int (*handler) (int, int);

     → 함수 포인터 handler의 선언이다. 이 함수 포인터는 반환자료형이 int 형이고, 두 개의 int형 인수를 가지는 함수를 가리킬 수 있다는 의미이다.

     → int (*) (int, int);로 변형된다. 그리고 처음에 함수 원형인 int plus(int, int) 역시 int (*) (int, int); 로 변형된다. 즉, 일치하므로 이상없이 대입된다.

    ⇒ if (op== '+') handler = plus;

     → 함수 포인터 handler이 plus() 함수를 가리키게 된다.

    ⇒ printf("the result is %d.\n", (*handler) (num1, num2));

     → 함수 포인터 handler을 이용하여 함수를 호출한다. 이때 포인터(*)를 생략하고 다음과 같이 호출할 수도 있다.

            printf("the result is %d.\n", handler(num1, num2));;

    ⇒ (*handler)(num1, num2) 는 C++ 방식이다. C에서도 사용되지만 C 문법으로 보면

     → handler(num1, num2); 이다. (둘 다 사용은 가능하다.)


    ※ int (*handle) (const char*, ...);

     → printf, scanf 둘다에 사용될 수 있다.





    - 배열 (같은 타입이 연속적으로 있는 것)

    ⇒ 사용자가 의미상의 연관이 있는 동일한 자료형에 속한 여러 개의 자료들을 묶어 하나의 이름으로 정의한 자료형.

    ⇒ 자료형 배열명[크기];

     → 자료형은 배열의 모든 원소가 가지는 공통적인 자료형으로 어떤 자료형도 올 수 있다.

     → 배열명은 사용자가 정의하는 배열의 이름.

     → 크기는 배열이 가지는 원소의 개수를 나타내며 항상 양의 정수로 명시되고, 대괄호 [ ]로 둘러싸인다.

     → 배열의 각 원소는 대괄호의 색인으로 나타낸다. 만약 int A[2]라면 배열의 각 원소는 A[0], A[1]


    #include<stdio.h>

    int main()

    {

            int a;

            int A[2];

            a = 10;


            printf("&a = %8X\n", &a); // a의 주소 값

            printf("A = %8X\n", A); // 배열 A의 주소

            printf("&A = %8X\n", &A); // 배열 전체의 주소(A의 주소와 같다.)

            printf("A+1 = %8X\n", A+1); // A+1은 type*1, 즉 포인터라는 뜻이다.

            printf("&A+1 = %8X\n", &A+1); /* &A는 배열 전체를 뜻하기 때문에 &A+1은 통째로 주소가 이동한다. */

            printf("&A[0] = %8X\n", &A[0]); /* A[0]의 주소는 A의 주소와 같으며 A+0과 같다. */

            printf("&A[1] = %8X\n", &A[1]);  // A[1]의 주소는 A+1과 같다.

            //printf("A = %d\n", A);


            return 0;

    }

    ⇒ 실행결과

            

    ⇒ A는 배열의 시작 주소이자 원소 하나하나를 가리키는 포인터이다.

    ⇒ A와 &A는 주소가 같지만 다른 것을 말한다. &A는 배열 전체를 뜻한다. 그렇기에 A+1은 type*1과 같아서 int형 4만큼 증가했지만 &A+1의 경우에는 배열 전체에 1을 더한 것이기에 A[2]의 배열 전체+1을 가리키는 것은 BFFFF858로 8만큼 주소가 증가했다. 만약 A[10]이라면 40만큼 더해져 16진수 28만큼 더해진 BFFFF78의 주소값이 나올 것이다.


    A[2] = {1.2};

     → A[0],A[1]에 각각 1과 2의 값이 들어간다.

    ※ *& 두 개는 만나면 상쇄된다.

     → *&A[0] = *(&A[0]) = *(A+0)

    ⇒ A[10] = {1, 2};

     → printf로 출력하면 A[2]부터 A[9]까지 모두 값이 0이다.

    ⇒ A[10] = { };

     → 모두 값이 0으로 채워진다.


    ※ 배열에는 &를 붙이지 않고, scanf에서 입력을 받는다.


            int str[20];

            scanf("%s",str);


    → str은 배열이므로 str 자체가 주소이다. 즉, &를 붙이지 않는다. (붙이면(→&str) str 배열 전체를 의미하게 되어 버린다. 하지만 &str도 시작주소를 의미하게 되므로 출력은 되나 형식적으로 주소 앞에 주소를 붙인 것이 되어 형식상으로는 warning에 가깝다.)


    - 2차원 배열

    int array[10][10];

    printf("%d\n",sinzeof(arr)); → 400 출력(400byte)


    → printf("array = %08X\n",array); // 출력결과 BFFFF6E4

    → printf("array+1 = %08X\n",array+1); // 출력결과 BFFFF70C → 28(hex)의 차이가 난다. 즉, array+1씩 한다는 것은 한 줄(행)씩 이동한다.

            

    배열식 표기법

    포인터

     array[0]

     array[1]

    array + 0

    array + 1

    ⇒ array+0+1 = array+1 (줄 이동 → 1줄의 주소)

    ⇒ array[0]+1 (칸 이동 → 1개의 주소)

    ⇒ &array[0]+1 (줄 이동 → 1줄의 주소)

    ※ *(array+0)+1 → array[0]+1

    ※ *( )는 [ ]와 같다.



    Posted by 동화다아아
    , |

    최근에 달린 댓글

    최근에 받은 트랙백

    글 보관함