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) */
}
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);
}
댓글