책정리/혼자 연구하는 C,C++ 1

11장 배열과 포인터

GONII 2015. 2. 19. 17:08

11.1 첨자 연산

11.1.1 배열의 내부적 처리

  • C언어 배열의 특징
  • C는 내부적으로 1차원 배열만 지원한다. 2차원 이상의 다차원 배열은 1차원 배열의 확장에 불과하다. C에는 2차원 배열이라는 것이 없다.
  • 배열을 구성하는 배열 요소의 타입에는 전혀 제한이 없다. T형 변수를 선언할 수 있으면 T형 배열도 언제나 선언할 수 있다. 배열도 유도형 타입의 일종이며 따라서 배열 그 자체가 배열의 요소가 될 수 있다.

    부분 배열 (SubArray) : 다른 배열에 포함된 배열

    전체 배열 (모배열) : 부분 배열을 배열 요소로 가지는 배열

       

    배열이 내부적으로 어떻게 처리되는가에 따라서 큰 차이점이 발생하는데 바로 1. 첨자 연산 방법과 2. 부분 배열의 자격 문제가 달라진다. 다차원 배열에서는 부분 배열만 단독으로 사용할 수 없지만 배열의 배열에서는 부분 배열 단독으로도 배열로 인정된다는 큰 차이점이 있다.

  • 예제 SubArray

#include <stdio.h>

   

void                arDump( void *array, int length ) ;

   

void                main ( void )

{

unsigned char ari[2][3] = { {1, 2, 3}, {4, 5, 6} } ;

   

arDump (ari, sizeof(ari)) ;

arDump (ari[0], sizeof(ari[0])) ;

arDump (ari[1], sizeof(ari[1])) ;

}

   

void                arDump( void *array, int length )

{

int                i;

for ( i = 0 ; i < length ; i++ )

{

printf("%02X ", *((unsigned char *)array+i));

}

printf("\n");

}

   

  • 예제 SubArray2

#include <stdio.h>

   

void main ( void )

{

char ar[] = "한국을 빛낸 사람들";

char ars[2][3][10] = {

{ "이순신", "강감찬", "김유신" },

{ "유관순", "을지문덕", "신사임당" }

} ;

   

printf("ar 배열 = %s\n", ar) ;

printf("ar[1][1] = %s\n", ars[1][1]);

}

11.1.2 [ ]연산자

ptr이 임의의 배열을 가리키는 포인터이고 n이 정수 일 때

ptr[n] = *(ptr+n)

   

  • 예제 ArrayIndex

#include <stdio.h>

   

void main ( void )

{

int ar[5] = { 1,2,3,4,5 } ;

   

printf("ar[2] = %d\n", ar[2]) ;

printf("ar[2] = %d\n", *(ar+2)) ;

printf("ar[2] = %d\n", 2[ar]) ;

}

ptr[ n ] == ptr+2 == *(ptr+n)

ar[2][1] == *(*(ar+2)+1)

  • ar+2

   

  • *(ar+2)

  • *(ar+2)+1

   

  • *(*(ar+2)+1)

  • 예제 ArrayIndex2

#include <stdio.h>

   

void main ( void )

{

int ar[3][4] = {{1,2,3,4}, {5,6,7,8}, {9,10,11,12}} ;

   

printf("ar[2][1] = %d\n", ar[2][1]) ;

printf("ar[2][1] = %d\n", *(*(ar+2)+1)) ;

   

printf("sizeof(ar+2) = %d\n", sizeof(ar+2)) ;

printf("sizeof(*(ar+2)) = %d\n", sizeof(*(ar+2))) ;

printf("sizeof(*(ar+2)+1) = %d\n", sizeof(*(ar+2)+1)) ;

}

  • 배열명은 포인터 상수 이다.
  • 포인터와 정수끼리 덧셈하면 sizeof(T)만큼 이동하고 그 결과는 포인터이다.
  • *연산자는 포인터가 가리키는 번지의 내용을 읽는다.

11.2 포인터 배열

11.2.1 정의

포인터 배열(Array of Pointer)이란 요소가 포인터형인 배열이다.

int *arpi[5] ; // 포인터 변수 다섯 개

  • 예제 PointerArray

#include <stdio.h>

   

void main ( void )

{

char *arps[] = {"고양이", "개", "오랑우탄", "돼지", "지렁이"} ;

int i ;

for ( i = 0 ; i < 5 ; i++ )

{

printf("%d\n", arps[i]) ;

}

}

11.2.2 포인터 배열의 활용

  • 예제 PASung

#include <stdio.h>

   

void main ( void )

{

int *ar[3] ;

int num[3] ;

int i ;

   

for ( i = 0 ; i < 3 ; i++ )

{

printf("%d반의 학생수를 입력하세요 : ", i+1) ;

scanf("%d", &num[i]) ;

ar[i] = (int *)malloc(sizeof(int)*num[i]) ;

}

   

//< 여기서 성적을 처리한다.

   

for ( i = 0 ; i < 3 ; i++ )

{

free(ar[i]) ;

}

}

  

   

11.2.3 포인터와 배열

실행 도중 동적으로 메모리를 할당하면 *포인터형 변수로도 정수형 배열을 가리킬 수 있다.

pi = (int *)malloc(sizeof(int) * n) ;

이렇게 하면 pi도 정수형 배열처럼 행세할 수 있음

  • 포인터는 변수인데 비해 배열은 상수이다.
  • pi가 가리키는 배열의 크기는 동적으로 결정 할 수 있지만 ar이 가리키는 배열의 크기는 선언할 때 정적으로 결정된다.
  • 배열은 그 자체가 크기 때문에 함수의 인수로 전달할 수 없지만 포인터는 대상체가 무엇이든간에 4바이트의 크기밖에 차지하지 않으므로 함수로 전달할 수 있다.
  • 포인터는 대상체로 직접 이동해서 바로 읽으므로 액세스 속도가 빠르다.

   

int **papi ;

11.3 배열 포인터

11.3.1 배열 포인터

  • 포인터 배열(Array of Pointer) : 그 원소가 포인터인 배열이다.
  • 배열 포인터(Pointer to Array) : 배열의 번지를 담는 포인터 변수이다.

    배열 포인터는 결국 포인터이다.

  • 예제 ArrayPointer

#include <stdio.h>

   

void main ( void )

{

char arps[5][9] = {"고양이", "개", "오랑우탄", "돼지", "지렁이"} ;

   

char (*ps)[9] ;

int i ;

ps = arps ;

   

   

for ( i = 0 ; i < 5 ; i++ )

{

printf("%s\n", *ps++) ;

}

}

11.3.2 배열 인수

  • 예제 ArrayArg

#include <stdio.h>

   

int GetTotaForWeek(int (*pa)[7]) ;

   

void main ( void )

{

int i;

int ari[][7] = {

{1,2,3,4,5,6,7},

{8,9,10,11,12,13,14},

{15,16,17,18,19,20,21}

} ;

   

for ( i = 0 ; i < 3 ; i++ )

{

printf("%d 주의 판매량 = %d\n", i+1, GetTotaForWeek(&ari[i])) ;

}

}

   

int GetTotaForWeek(int (*pa)[7])

{

int i, sum = 0 ;

   

for ( i = 0 ; i < 7 ; i++ )

{

sum += pa[0][i] ;

}

return sum ;

}

11.3.3 배열 인수 표기법

  • 예제 ArrayPara1

#include <stdio.h>

   

void OutArray(int ar[5]) ;

   

void main ( void )

{

int ar[] = {1,2,3,4,5} ;

   

OutArray(ar) ;

}

   

void OutArray(int ar[5])

{

int i ;

for (i = 0 ; i < 5 ; i++ )

{

printf("%d번째 = %d\n", i, ar[i]) ;

}

}

void OutArray(int ar[]) == void OutArray(int *ar) == void OutArray(int ar[5])

   

  • 예제 ArrayPara2

#include <stdio.h>

   

int GetArSum(int ar[], int size) ;

   

void main ( void )

{

int ar[] = {1,2,3,4,5} ;

int ar2[] = {6,7,8,9,10,11} ;

   

printf("총합 = %d\n", GetArSum(ar, sizeof(ar)/sizeof(ar[0])));

printf("총합 = %d\n", GetArSum(ar2, sizeof(ar2)/sizeof(ar2[0])));

}

   

int GetArSum(int ar[], int size)

{

int i, sum = 0 ;

   

for ( i = 0 ; i < size ; i++ )

{

sum += ar[i] ;

}

return sum ;

}

11.3.4 이차 배열 인수

  • 예제 TwoArrayPara

#include <stdio.h>

   

void func(int (*ar)[3], int size)

{

int i, j;

   

for ( i = 0 ; i < size ; i++ )

{

for ( j = 0 ; j < 3 ; j++ )

{

printf("ar[%d][%d] = %d\n", i, j, ar[i][j]);

}

}

puts("") ;

}

   

void main ( void )

{

int ar1[2][3] = {{1,2,3}, {4,5,6}} ;

int ar2[3][3] = {{7,8,9}, {10,11,12}, {13,14,15}} ;

   

func(ar1, 2) ;

func(ar2, 3) ;

}

11.3.5 이차 배열 할당

char *p = (char *[4])malloc(sizeof(char)*3*4) ;

free(p) ;

  • 예제 malloc2array

#include <stdio.h>

#include <string.h>

   

void main ( void )

{

int i ;

   

char (*p)[4] = (char (*)[4])malloc(sizeof(char)*3*4) ;

strcpy(p[0], "dog") ;

strcpy(p[1], "cow") ;

strcpy(p[2], "cat") ;

for ( i = 0 ; i < 3 ; i++ )

{

puts(p[i]) ;

}

free(p) ;

}

  • 예제 malloc2array2

#include <stdio.h>

#include <string.h>

   

void main ( void )

{

int n = 3, m = 4 ;

int i ;

   

char **p ;

p = (char **)malloc(sizeof(char *)*n) ;

   

for ( i = 0 ; i < n ; i++ )

{

p[i] = (char *)malloc(sizeof(char)*m) ;

}

   

strcpy(p[0], "dog") ;

strcpy(p[1], "cow") ;

strcpy(p[2], "cat") ;

   

for ( i = 0 ; i < n ; i++ )

{

free(p[i]) ;

}

free(p) ;

}

  

11.3.5 &ar

  • 예제 ampersandarray

#include <stdio.h>

   

void main ( void )

{

int ar[5] = {1,2,3,4,5} ;

int *p1 ;

int (*p2)[5] ;

   

p1 = ar ;

p2 = &ar;

   

printf("before = %p\n", p1) ;

printf("before = %p\n", p2) ;

p1++ ;

p2++ ;

   

printf("before = %p\n", p1) ;

printf("before = %p\n", p2) ;

}

11.4 배열과 문자열

11.4.1 문자열 상수

  • 예제 StringConst

#include <stdio.h>

   

void main ( void )

{

char name[] = "Yoo Dong Gon" ;

   

printf("This is a string Const\n") ;

puts(name) ;

}

  

11.4.2 문자 배열 초기화

char str[] = "korea" ;

" " 으로 묶어서 선언 부분에 초기화

11.4.3 문자형 포인터

  • 예제 CharArray

#include <stdio.h>

   

void main ( void )

{

char str[] = "korea" ;

char *ptr = "korea" ;

   

puts(str) ;

puts(ptr) ;

   

ptr = "china" ;

// str = "china" ;

   

str[0] = 'C' ;

//ptr[0] = 'C' ;

}

   

11.4.4 문자열 배열

  • 예제 StringArray

#include <stdio.h>

   

void main ( void )

{

char arCon[][32] = {"korea", "america", "iran", "russia"} ;

int i;

   

for ( i = 0 ; i <sizeof(arCon)/sizeof(arCon[0]) ; i++ )

{

puts(arCon[i]) ;

}

}

  • 예제 StringArray2

#include <stdio.h>

   

void main ( void )

{

char *pCon[] = {"korea", "america", "iran", "russia"} ;

int i;

   

for ( i = 0 ; i < sizeof(pCon)/sizeof(pCon[0]) ; i++ )

{

puts(pCon[i]) ;

}

}

  

   

  • 예제 String2Array

#include <stdio.h>

   

void main ( void )

{

int x, y ;

char arCon[][4][32] =

{

{"대한민국", "일본", "북조선 인민주의 공화국", "베트남"},

{"미국", "브라질", "칠레", "아르헨티나"},

{"영국", "헝가리", "체코슬로바키아", "루마니아"},

{"남아프리카 공화국", "우간다", "나이지리아", "케냐"},

{"오스트레일리아", "뉴질랜드", "유동곤", "공화국"}

} ;

   

for ( y = 0 ; y < 5 ; y++ )

{

for ( x = 0 ; x < 4 ; x++ )

{

printf("%s", arCon[x][y]) ;

if( x != 3 )

{

printf(", ") ;

}

}

puts("") ;

}

}

   

중요 개념

  • &, * 연산자의 기능과 포인터로 변수를 간접적으로 참조하는 방법
  • 함수가 참조 호출로 실인수 값을 변경하는 방법과 원리
  • 포인터가 타입을 가지는 이유와 포인터 연산의 동작
  • 포인터를 이용한 동적 메모리 할당

   

반응형

'책정리 > 혼자 연구하는 C,C++ 1' 카테고리의 다른 글

13장 구조체  (0) 2015.02.19
12장 문자열 함수  (0) 2015.02.19
10장 포인터  (0) 2015.02.19
9장 배열  (0) 2015.02.19
8장 표준 함수  (0) 2015.02.19