내장형 하드웨어/C언어

C언어 - 배열의 값과 주소 표시법, 함수 포인터 배열

동화다아아 2011. 7. 4. 17:07
 

- 배열 array의 값과 주소 표시법


#include<stdio.h>
int main()
{
        
int i;
        
int j;
        
int array[3][4= {{15,23,45,56},
                        {
34,52,76,23},
                        {
43,62,91,84}};
        printf(
"========================\n");
        printf(
"array         : %08X\n", array); // 첫 번째 줄의 주소
        
printf("array[0][0]   : %08X\n"&array[0][0]); 
        printf(
"array[0]      : %08X\n", array[0]);  
        printf(
"&array[0]     : %08X\n"&array[0]);  
        printf(
"========================\n");

        printf("array+1       : %08X\n", array+1); 
              
// 행의 이동(이름은 배열 전체가 아니라 한줄(행)을 뜻한다.)
        
printf("array[0][0]+1 : %08X\n"&array[0][0]+1); // 열의 이동
        
printf("array[0]+1    : %08X\n", array[0]+1);  // 열의 이동
        
printf("&array[0]+1   : %08X\n"&array[0]+1); // 행의 이동
        
printf("========================\n");
    
        printf(
"array         : %08X\n", array);
        printf(
"*array        : %08X\n", *array); 
                  
// array와 같은 값이 출력되지만 다르다.
        
printf("*array+1      : %08X\n", *array+1); 
                  
// 열의 이동(4만큼 증가했다.
        
printf("**array       : %d\n", **array); // array의 값이 출력된다.
        
printf("&array+1      : %08X\n"&array+1);
                  
// 10진수로 48만큼 증가했다.

        return 0;

⇒ 출력결과         

 



#include<stdio.h>
int main()
{
        
int i;
        
int j;
        
int array[3][4= {{15,23,45,56},
                {
34,52,76,23},
                {
43,62,91,84}};

        printf(
"===========================\n");
        printf(
"&array[2][3]    : %08X\n"&array[2][3]); // array[2][3]의 주소
        
printf("array[2]        : %08X\n", array[2]); // array[2][0]의  주소
        
printf("array[2]+3      : %08X\n", array[2]+3); // array[2][3]의 주소
        
printf("array+2         : %08X\n", array+2); // array[2][0]의 주소
        
printf("array+2+3       : %08X\n", array+2+3); // array[5]의 주소
        
printf("*(array+2)+3    : %08X\n", *(array+2)+3); // array[2][3]의 주소
  
        printf(
"===========================\n");
        printf(
"array[2][3]     : %d\n", array[2][3]); // array[2][3]의 값
        
printf("*(*(array+2)+3) : %d\n", *(*(array+2)+3)); // array[2][3]의 값
        
printf("*(array[2]+3)   : %d\n", *(array[2]+3)); // array[2][3]의 값
  
        printf(
"===========================\n");
        
return 0;
}

⇒ 출력 결과         

 


⇒ 

배열

포인터

혼합

&array[2][3]

*(array+2)+3

array[2]+3

 → 배열 자체를 가리키면 &를 붙여야 한다.

 → [ ]가 없어지기 위해 *가 붙는다.

 → array[2][3] → *(array[2]+3)

 → array[2] → *(array+2)

 → **array+3 == *(*array+0)+0) → 값

 → *array+3 == &array[0][3] → 주소

※ C는 배열과 포인터를 같게 본다.

※ 값인지 주소인지를 알려면 예를 들어 2차원이라면 ‘*’ or ‘[ ]’ 개수가 2개면 값, 하나면 주소이다.

        printf("array[0][1]     : %d\n", array[0][1]);
        printf(
"*(*array+1)     : %d\n", *(*array+1));
        printf(
"*(array[0]+1)   : %d\n", *(array[0]+1));

        printf("*(*(array+0)+1)   : %d\n", *(*(array+0)+1));

⇒ 출력화면         

 



- 형식인수로 다차원 배열이 사용되는 경우

⇒ 다차원 배열이 형식인수로 사용되는 경우에는 첫 번째 색인을 생략할 수 있다. 그러나 두 번째 색인부터는 모두 명시해 주어야 한다. 이것은 배열 크기를 컴파일러에게 알려 주어야 하기 때문이다.


// 행렬의 대각선의 합 (1, 1) + (2, 2) + (3, 3)을 구하는 프로그램
#include<stdio.h>
int sum_matrix(int mat[][3]);
int main()
{
        
int sum;
        
int mat[3][3= {{13,23,15},{11,8,25},{17,14,21}};

        sum 
= sum_matrix(mat);
        
// 배열을 넘기는 인자 형식에 주의
        
printf("Answer : %d\n", sum);

        
return 0;
}
int sum_matrix(int mat[][3])
{
        
int i;
        
= mat[0][0] + mat[1][1] + mat[2][2];

        
return (i);
}

⇒ 출력 결과         

 

⇒ 형식 인수 int mat[][3]에서와 같이 첫 번째 색인은 생략되지만, 두 번째 색인부터는 명시한다. 3차원 배열에서 형식인수 표기의 예는 다음과 같다.

                int sum (int m[][7][4])




- 함수 포인터의 배열

⇒ 응용 프로그램에서는 함수 포인터로 구성된 배열이 많이 사용된다. 함수 포인터로 구성된 배열의 선언 형식은 다음과 같다.

        반환자료형 (*배열이름 [배열 크기]) (인수 리스트)

⇒ 다음 사칙연산을 계산하는 함수를 위한 포인터 배열을 가정할 때, 다음과 같은 배열을 선언할 수 있다.

        int (*hanlde[4]) (int, int);

 → 이 때 배열의 각 원소는 함수의 시작주소를 가진다.


// 사칙연산을 계산하는 함수를 위한 함수 포인터의 배열
#include<stdio.h>

int get_operator();
int plus(intint);
int minus(intint);
int multiply(intint);
int divide(intint);

int get_operator()
{
        
int choice;
        
while(1)
        {
                printf(
"=======================\n");
                printf(
"0 : for plus\n");
                printf(
"1 : for minus\n");
                printf(
"2 : for multiply\n");
                printf(
"3 : for divide\n");
                printf(
"4 : for quit\n");
                printf(
"=======================\n");
                printf(
"Please Enter operator: ");
                scanf(
"%d"&choice);
                
if((choice >= 0&& (choice <=4))
                {
                        
return (choice);
                }
                
else
                
{
                        printf(
"Wrong Input, enter again!\n");
                }
        }
        
return 0;
}      

int main()
{
        
int op;
        
int num1, num2;
        
int result;
        
int (*hanlde[4]) (intint= {plus, minus, multiply, divide};

        
while(1)
        {
                op 
= get_operator();
                
if(op == 4)
                {
                        printf(
"This is the end of program!\n");
                        
return 0;
                }
                printf(
"Enter the first operand : ");
                scanf(
"%d"&num1);
                printf(
"Enter the second operand :");
                scanf(
"%d"&num2);

                result 
= hanlde[op] (num1, num2);
                printf(
"\nthe result of operation is %d\n\n", result);
        }
        
return 0;
}
int plus(int n1, int n2)
{
        
return (n1+n2);
}
int minus(int n1, int n2)
{
        
return (n1-n2);
}
int multiply(int n1, int n2)
{
        
return (n1*n2);
}
int divid0e(int n1, int n2)
{
        
return (n1/n2);
}

⇒ 출력 결과         

 


⇒ int (*hanlde[4]) (int, int) = {plus, minus, multiply, divide};

 → 네 개의 원소를 가진 함수 포인터의 배열을 선언하고, 초기화 하는 부분이다.

⇒ result = hanlde[op] (num1, num2);

 → 해당 함수를 호출하는 부분

⇒ 함수 포인터는 임베디드 시스템에서 인터럽트 처리 테이블이나 이벤트 처리할 때처럼, 상황에 따라 호출하는 함수가 다를 경우 유용하게 사용된다.