IT 과학/C언어

C언어 | 포인터 응용

곰뚱 2019. 12. 29.

TIP
 
 

 

 

 

1. 응용

(1) 포인터 배열

확인문제 1

/* 포인터 배열의 각 원소의 대상체가 배열인 경우 포인터 배열의 사용 방법 */
#include <stdio.h>
void main(void)
{
      int a[3] = {11, 22, 33}, i, j;
      int b[3] = {44, 55, 66};
      int *pointer[2];

      pointer[0] = a;
      pointer[1] = b;
      for( i = 0; i < 2; i++)
      {
          if( i == 0)
              printf("i = %d, pointer[i] = %u, a = %u\n", i, pointer[i], a);
          else
              printf("i = %d, pointer[i] = %u, b = %u\n", i, pointer[i], b);
          printf("----------------------------------------\n");
          for(j = 0; j < 3; j ++)
          {
              if( i == 0)
                  printf("(pointer[i])+j = %u, a+j = %u, *(pointer[i]+j) = %d\n",
                         (pointer[i]) + j, a + j, *(pointer[i] + j) );
            else
                  printf("(pointer[i])+j = %u, b+j = %u, *(*(poiner+i)+j)= %d\n",
                         (pointer[i]) + j, b + j, *(*(pointer +i ) + j));
          }
          putchar('\n');
      }
}

 

(2) 포인터의 포인터

확인문제 2

/* 포인터의 포인터를 연산을 확인하는 프로그램 */
#include <stdio.h>
void main(void)
{
      int a = 55, *pt, **ppt, ***pppt;

      pt = &a;
      ppt = &pt;
      pppt = &ppt;

      printf("a = %d, *pt = %d, **ppt = %d, ***pppt = %d\n",
            a, *pt, **ppt, ***pppt);
      printf("&a = %u, pt = %u, *ppt = %u, **pppt = %u\n",
            &a, pt, *ppt, **pppt);
      printf("&pt = %u, ppt = %u, *pppt = %u\n", &pt, ppt, *pppt);
      printf("&ppt = %u, pppt = %u\n",&ppt, pppt);
}

 

(3) 포인터 배열의 포인터

확인문제 3

/* 포인터 배열의 포인터 변수의 사용 */
#include <stdio.h>
void main(void)
{
      char *pt[3], **ppt;
      int i;

      ppt = pt;

      ppt[0] = "The ";
      ppt[1] = "C  ";
      ppt[2] = "Programming!!\n";

      for(i = 0; i < 3; i++)
        printf("%s", *(ppt + i));
}

 

확인문제 4

/* 2차원 포인터 배열의 포인터의 사용 */
#include <stdio.h>
void print_address(char *[ ]);
void print_content(char *[ ][3]);
void main(void)
{
      char *address[3];
      char *content[3][3];

      /* 1차원 포인터 배열 address의 각 원소의 초기화 */
      address[0] = "name";
      address[1] = "city";
      address[2] = "phon-num";

      /* 2차원 포인터 배열 content의 각 원소의 초기화 */
      content[0][0] = "Jung Sung Min";
      content[0][1] = "Soon chun";
      content[0][2] = "746-5322";
      content[1][0] = "Kim Sung Sik";
      content[1][1] = "Kwang Ju";
      content[1][2] = "263-6520";
      content[2][0] = "Yang Sung Ho";
      content[2][1] = "Soon chun";
      content[2][2] = "742-1534";

      print_address(address);
      print_content(content);
}

void print_address(char **add)
{
      int i;

      for(i = 0; i < 3; i++)
        printf("%-18s  ", *(add + i));
      putchar('\n');
      printf("--------------------------------------\n");
}
void print_content(char *con[ ][3])
{
      int i, j;

      for(i = 0; i < 3; i++)
      {
        for(j = 0; j < 3; j++)
            printf("%-20s", con[i][j]);
        putchar('\n');
      }
}

 

(4) void형 포인터와 널 포인터

확인문제 5

/* void형 포인터의 사용의 예 */
#include <stdio.h>
void main(void)
{
      int array[3] = {333, 555, 777};
      char string[ ] = "VOID POINTER";
      void *pv;

      pv = array;

      printf("*((int *)pv + 0)) = %d\n", *((int *)pv + 0));
      printf("((int *)pv)[1] = %d\n", ((int *)pv)[1]);
      pv = ((int *)pv) + 2;
      printf("*(int *)pv = %d\n", *(int *)pv);
      ((int *)pv)--;
      printf("(int *)pv = %d\n", *(int *)pv);

      pv = string;

      printf("(char *)pv = %s\n", (char *)pv);
      printf("(char *)pv + 5 = %s\n", (char *)pv + 5);
      printf("(char *)pv[5] = %s\n", (char *)pv + 5);
      printf("*((char *)pv + 5 = %c\n", *((char *)pv + 5));
      printf("((char *)pv)[5] = %c\n", ((char *)pv)[5]);
      ((char *)pv)++;
      printf("*(char *)pv = %c\n", *(char *)pv);
}  

 

확인문제 6

/* void형 포인터의 활용의 예 */
#include <stdio.h>
#define SIZE 3
void print_array(void *, int);
void main(void)
{
      int array_1[SIZE] = {333, 555, 777};
      double array_2[SIZE] = {0.123, 0.1234, 0.12345};

      print_array(array_1, sizeof(*array_1));
      print_array(array_2, sizeof(*array_2));
}

void print_array(void *pv, int size)
{
      int i;

      if( size == 2) /* int형 배열 array_1의 출력 */
      {
          for(i = 0; i < SIZE; i++)
              printf("array_1[%d] = %-12d", i, ((int *)pv)[i]);
          putchar('\n');
      }
      else /* double형 배열 array_2의 출력 */
      {
          for(i = 0; i < SIZE; i++)
              printf("array_2[%d] = %-12.5lf", i, ((double *)pv)[i]);
          putchar('\n');
      }
}

 

(5) 함수 포인터

확인문제 7

/* 함수 포인터의 사용 */
#include <stdio.h>
int *power(int *, int);
int mult(int, int);
void main(void)
{
      int *(*pf1)(int *, int);
      int (*pf2)(int, int);
      int array[5] = { 1, 2, 3, 4, 5};
      int size, i, *pt;

      pf1 = power;
      pf2 = mult;
      size = sizeof(array) / sizeof(int);

      pt = (*pf1)(array, size);
      printf("sum = %d\n", *pt);
      for( i = 0; i < size; i++)
        printf("array[%d] = %3d\n", i, array[i]);
      printf("%d * %d = %d\n", 6, 7, (*pf2)(6, 7));
}

int *power(int array[ ], int n)
{
      int i, sum = 0;

      /* 배열 array의 각 원소에 2을 곱하고, 그 합을 구한다 */
      for(i = 0; i < n; i++)
      {
        array[i] *= 2;
        sum += array[i];
      }
      return(&sum);
}

int mult(int a, int b)
{
      return(a * b);
}

 

확인문제 8

/* 함수의 전달 인수로 사용되는 함수 */
#include <stdio.h>
int sum(int, int);
int total(int (*)(int, int), int);
void main(void)
{
      int a = 3;

      printf("result = %d\n", total(sum, a));
}

int total(int (*pf)(int, int), int n)
{
      int result = 0, i;

      for( i = 1; i < n; i++)
        result += (*pf)(n + i, i) + (*pf)(n - i, i);
      return(result);
}

int sum(int i, int j)
{
      return(i + j);
}

 

<요약>

1. 배열에 대한 pointer

 

        #include <stdio.h>

        int temp[100] = { 10, 20, 30, 40 };

        main()
        {
                int *p = temp, *q = &temp[0];

                printf("temp = %u, p = %u, q = %u\n", temp, p, q);
                printf("p+1 = %u, p+2 = %u\n", p+1, p+2);
                printf("*p = %d, *(p+1) = %d, *p+1 = %d\n", *p, *(p+1), *p+1);
        }

        ※ *(p+1)과 *p+1은 다르다.

 

2. 함수의 배열 인자(parameter)

 

        #include <stdio.h>

        int days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

        main()
        {
                f(days);  /* 또는 f(&days[0]); */
        }

        f(pd)
        int pd[];  /* 또는 int *pd; */
        {
                int i;

                for (i = 0; i < 12; i++)
                        printf("%d\n", pd[i]);  /* pd[i]   *(pd+i) */
        }

728x90


3. 배열과 pointer의 차이점

 

   ●   배열 : 배열 크기만큼 memory 할당

                배열 이름에는 주소를 assign할 수 없음

    ●  pointer : 정수 크기(2 or 4 bytes)만큼 memory 할당

                pointer 변수에는 주소를 assign할 수 있음

 

4. pointer 연산

 

int i = 100;

int *p = &i;

 

① 대입문(assignment) : p = &i;

② value access : *p

③ pointer 변수의 주소 사용 가능 : &p

④ 증감 연산 가능 : p++, --p, p=p+i

⑤ 두 pointer 변수의 차 : p-q

 

5. 다차원 배열 (multi-dimensional array)

① 선언(declaration)

short a[10][3];

char  b[10][20][5];

 

② 초기화

short a[10][3] = { {5, 6}, {7, 8} };

short a[10][3] = { 5, 6, 7, 8 };

 

③ pointer

short a[10][3] = { {5, 6}, {7, 8} };

short *p = a, *q = a[3];

 

④ 함수의 인자

                main()
                {
                        short a[10][3];
                        ......
                        f(a);
                }

                f(x)
                short x[][3];  /* 또는 short (*x)[3]; */
                {
                        ......
                }

 

※ pointer의 의미 --- 매우 중요함

가. int *p;  ---  pointer 변수 p, 정수 크기(2 or 4 bytes) memory, int *가 저장됨

나. int *p[n];  ---  pointer 배열 p, n개의 memory 할당,

                            p[0], …, p[n-1]에 int *가 저장됨

다. int (*p)[n];  ---  pointer 변수 p, 정수 크기(2 or 4 bytes) memory,

                           크기 n인 정수형 배열 구조를 갖는 주소가 저장됨

라. int *p()[];   ---  함수 p의 선언, 'return값이 int pointer 배열'인 함수 p

마. int *p();    ---  함수 p의 선언, 'return값이 int pointer'인 함수 p

바. int (*p)();   ---  pointer 변수 p, 'return값이 int인 함수'의 주소가 저장됨

사. int (*p[])();  ---  pointer 배열 p, 'return값이 int인 함수'의 주소가 저장됨

 

● string --- NULL 문자로 끝나는 문자들의 sequence

● string 상수 --- 큰따옴표(")로 둘러싸인 문자들     static memory 영역에 할당됨

● string 초기화

        char s[20] = "abcde"; /* { 'a', 'b', 'c', 'd', 'e' } */
        char s[] = "abcde";   /* char *s = "abcde"; */

        ※ char s[20];  s = "abcde";       ERROR !!!

        char *s = "abc\ndef";
        char *s = "c:\\dos\\format.exe";
        char *s = "This is a \"test\" string.";

 

※ 배열과 pointer의 차이점

pointer에 저장되는 주소는 그 값이 변경되거나 다른 주소로 치환할 수 있으나,
배열 명칭은 그 배열에 할당된 memory의 첫번째 주소로 고정되어 변경될 수 없다.

        char *p = "abcde";         對   char q[] = "abcde";

        ① data access시에 둘 다 첨자 또는 pointer 연산자 사용 가능

                p[i-1]    q[i+1]    *(p+1)    *(q-1)

        ② 피연산자로 사용과 치환문은 pointer만 가능 : p+i, p++; --p; p = q;

                q+i, q++; --q; q = p; 는 허용되지 않음

 

● string 배열 : 다음 3가지 선언문의 차이점은?

        ① char *names[] = { "황신혜", "HOT", "spice_girls", "심혜진" };

                names[2] == "spicy_girls"
                *names[2] == 's'
                *(names[2]+1) == names[2][1] == 'p'

        ② char *names[4] = { "황신혜", "HOT", "spice_girls", "심혜진" };

        ③ char names[4][20] = { "황신혜", "HOT", "spice_girls", "심혜진" };


확인문제 9

/* 문자열 배열과 문자열 포인터의 관계를 확인하는 프로그램 */
#include <stdio.h>
void main(void)
{
      char array[ ] = "I love my wife";
      char *string = "I love my children";
      char *pt;

      printf("%s\n", array);
      printf("%s\n", string);
      pt = array;
      printf("%s\n", pt);
      printf("%s %s\n", array + 7, string + 7);
      printf("%c    %c\n", *(array + 10), string[10]);
 }

 

확인문제 10

/* 2차원 문자 배열에 의한 문자열 구현 */
#include <stdio.h>
void main(void)
{
      char multi_string[8][12] = {"File", "Edit", "Run", "Compile", "Project",
                                "Option", "Debug", "Break-watch"};

      int index, total = 0;

      for(index = 0; index < 8; index++)
         printf("%s\n", multi_string[index]);
      total = sizeof(multi_string);
      printf("Size of multi_string = %d bytes.\n", total);
      for(total = 0, index = 0; index < 8; index++)
         total += real_strlen(multi_string[index]);

      printf("Total real characters = %d bytes.\n", total);
}

int real_strlen( char *pt)
{
      int count = 0;

      while( *pt++ != '\0') count++;
      return(count + 1);
}

 

확인문제 11

/* 1차원 포인터 배열을 이용한 문자열 배열의 구현 */
#include <stdio.h>
void main(void)
{
      char *pt_string[8] = {"File", "Edit", "Run", "Compile", "Project",
                          "Option", "Debug", "Break-watch"};

      int index, total = 0;

      for(index = 0; index < 8; index++)
         printf("%s\n", pt_string[index]);
      total = sizeof(pt_string);
      printf("Size of pt_string = %d bytes.\n", total);
      for(index = 0; index < 8; index++)
         total += real_strlen(pt_string[index]);
      printf("Total real characters = %d bytes.\n", total);
}

int real_strlen( char *pt)
{
      int count = 0;

      while( *pt++ != '\0') count++;
      return(count + 1);
}


● string 입출력

        #include <stdio.h>

        main()
        {
                int i;
                char s[100];  /* char *s; 또는 char s[]; 라고 선언하면?? */

                scanf("%s %d", s, &i);  /* scanf("%3s %d", s, &i); 로 고치면?? */
                printf("%s, %d\n", s, i);
        }

 

확인문제 12

/* 입/출력 함수 scanf( )와 printf( )를 이용한 문자열 입/출력 */
#include <stdio.h>
void main(void)
{
     static char string[11], array[11], *spt;
     int count, i;

     spt = array;

     for(i = 1; i <= 4; i++)
     {
         printf("%d. Please enter 2 sring: ", i);
         count = scanf("%6s %10s", string, spt);
         printf("  I read the %d strings %s and %s.\n",
                       count, string, spt);
         fflush(stdin);
     }
}

 

● string 함수 : <string.h>

        ① ptr = gets(s);  /* return value : char pointer 또는 NULL */

                한 line을 입력함 ( line끝의 LF 문자는 제거 )

 

확인문제 13

/* gets( ) 함수의 특징을 설명하는 문자열 입력 프로그램 */
#include <stdio.h>
void main(void)
{
      char str_1[10], str_2[ ] = "aabbcc", *spt;

      spt = str_1;

      /* gets( ), puts( )를 사용한 문자열 입/출력 */
      printf("1. Input a string: ");
      if(gets(str_1) == NULL)
         puts("Can't allocate a string in str_1");
      else printf("str_1 = %s\n", str_1);

      /* gets( )의한 문자열 파괴 현상 */
      printf("2. Input a string: ");
      if(gets(spt) == NULL)
         puts("Can't allocate a string in str_1");
      else
      {
         printf("spt = %u, spt + 10 = %u, &str_2[0] = %u\n",
               spt, spt+10, str_2);
         printf("spt = %s\n", spt);
         printf("str_2 = %s\n", str_2);
      }

      /* NULL 포인터의 반환 */
      printf("3. Input a string: ");
      if(gets(str_1) == NULL)
         puts("Can't allocate a string in str_1");
      else printf("str_1 = %s\n", str_1);
}


        ② puts(s);  /* string s를 stdout으로 출력 --- appends a newline char. */

           char *s = "abcdefg"; 로 선언된 string s에 대해서
           puts(s+4); 와 puts(&s[4]); 은 모두 "efg"를 출력한 후에 줄바꿈을 한다.

 

확인문제 14

/* puts( ) 함수를 사용한 문자열의 출력하는 예제 */
#include <stdio.h>
void main(void)
{
      char *spt = "PUT STRING";
      char str[ ] = "put string\n";
      char string[22] = "I love C programming!!";

      puts(spt);
      puts(str);
      puts(string);
      puts(spt+4);
      puts(&str[4]);
}


        ③ n = strlen(s);  /* string s의 문자 개수, cf. sizeof(s) */

 

확인문제 15

/* strlen( ) 함수를 사용하여 문자열 길이를 구하는 프로그램 */
#include <stdio.h>
#include <string.h>
void main(void)
{
      char *spt = "PUT STRING";
      char str[ ] = "My first string";
      char string[22] = "I love C programming!";

      puts(spt);
      printf("The length of spt is %d\n\n", strlen(spt));
      puts(str);
      printf("The length of str is %d\n\n", strlen(str));
      puts(string);
      printf("The length of string is %d\n\n", strlen(string));
}


        ④ strcat(s, t);  /* string concatenation : s의 뒤에 t를 이어줌 */

 

확인문제 16

/* strcat( ) 함수를 사용하는 예제 프로그램 */
#include <stdio.h>
#include <string.h>
int real_string(char *);
void main(void)
{
      static char dest[31];
      char sour1[ ] = "String";
      char *sour2 = " Concatenation";
      char *sour3 = " Function", *spt;
      int size;

      if( sizeof(dest) > real_string(sour1))
      {
        strcat(dest, sour1);
        puts(dest);
      }

      size = real_string(dest);
      if((sizeof(dest) - size) > real_string(sour2))
      {
        strcat(dest, sour2);
        puts(dest);
      }

      size = real_string(dest);
      if((sizeof(dest) - size) > real_string(sour3))
      {
        strcat(dest, sour3);
        puts(dest);
      }
      printf("String of Array destination is \"%s\" \n", dest);
}

int real_string(char *spt)
{
      int count = 0;

      while(*spt++ != '\0') count++;
      return(count);
}


        ⑤ i = strcmp(s, t);  /* string s와 t가 같으면 i=0이고, 다르면 i≠0 */

                if (!strcmp(s,t))
                        printf("스트링 s와 t는 같다.\n");
                else
                        printf("스트링 s와 t는 다르다.\n");

 

확인문제 17

/* strcmp( ) 함수와 strcmp( ) 함수를 사용하는 예제 프로그램 */
#include <stdio.h>
#include <string.h>
#define ROW 8
#define COL 15
void change_name(char (*)[COL], int);
void main(void)
{
      register index;
      int enter = 0;
      char menu[COL];
      static char menu_list[ROW][COL] = {
                                    "File",
                                    "Edit",
                                    "Run",
                                    "Compile",
                                    "Project",
                                    "Option",
                                    "Debug",
                                    "Break_watch"
                                    };
      clrscr( );
      printf("Enter menu : ");
      gets(menu);
      for( index = 0; index < ROW; index++)
      {
          if( strcmp(menu_list[index], menu) == 0)
          {
              enter = 1;
              break;
          }
          continue;
      }
      if(enter == 1)
      {
          puts(menu_list[index]);
          puts("Search Success!!");
          change_name(menu_list, index);
          for(index = 0; index < ROW; index++)
              puts(menu_list[index]);
      }
      else
          puts("Search Fail");
}

void change_name(char (*pt)[COL], int n)
{
      char new[COL];

      printf("Enter new menu name: ");
      gets(new);
      strcpy(pt[n], new);
}


        ⑥ strcpy(s, t);  /* string t를 s에 복사 */

 

확인문제 18

/* strcpy( ) 함수를 사용하여 문자열을 복사하는 프로그램의 예 */
#include <stdio.h>
#include <string.h>
void main(void)
{
      char string[30], *pt;
      char *spt = "String copy function";

      pt = strcpy(string, spt);
      puts(spt);
      puts(string);
      puts(pt);
}

 

확인문제 19

/* strcpy( ) 함수의 활용 */
#include <stdio.h>
#include <string.h>
void main(void)
{
      char string[30], *pt;
      char *spt = "String copy function";

      pt = strcpy(string, spt);
      puts(pt);
      printf("string = %u, pt = %u\n\n", string, pt);

      pt = strcpy(string + 5, spt);
      puts(pt);
      printf("string = %u, pt = %u\n\n", &string[5], pt);

      pt = (string + 5, "data copy");
      puts(pt);
      printf("string = %u, pt = %u\n\n", string + 5, pt);

}

 

 

 

그리드형

댓글