포인터배열
: 포인터의포인터
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
■
포인터도일종의변수이므로포인터로이루어진배열도가능하다
.
문자열과포인터
.
■
문자열과
포인터의
차이
str
rose\0
char str[] = "rose"; // array 배열이름
문자열
char *pstr = "rose"; // pointer
위의
두
정의에는
중요한
차이가
있다
. pstr rose\0 ☞
포인터이름
문자열
■
str은
배열이고
끝에
‘\0’이
있고
, 각각의
문자를바꿀
수
있다
.
각각의
문자는
일정한
기억장소에
기록되어
있다
.
■
pstr은
포인터이며
, 위의경욪
문자엱
상수
"rose" 륹
가리킨다
. 따라서
가리키는
위치륹
바꿀
수
있지만
문자륹
바꿀
수는
없다
.
문자열과포인터
..
■
문자열과
포인터의
차이
#include
int main(void)
{
char str[] = "rose"; // array
char *pstr = "rose"; // pointer
printf("%s\n", str);
str[1] = 'u'; printf("%c\n", str[1]);
printf("%s\n", str);
printf("%p %s\n", pstr, pstr);
pstr = "rose is rose";
printf("%p %s\n", pstr, pstr);
return 0;
}
■
결과
rose
u
ruse
00415760 rose
0041573C rose is rose
포인터배열
(array of pointers) .
■
문자열의
배열
char *pstr = "fruit"; // 문자열
char *name[] = { "apple", "pear", "banana", "orange" }; // 문자열
배열
문자열의
배열은
포인터
배열로
처리한다
.
name[0]
name[1]
name[2]
☞
☞
☞
☞
apple\0
pear\0
banana\0
orange\0
pstr
☞
fruit\0
포인터
문자열
name[3]
포인터
배열
문자열
배열
포인터배열
(array of pointers) ..
■
정수배열의
포인터배열
정수배엱
int num[] = { 5,6,4 } 에서
최소값
, 중간값, 최대값읁
가리키는
포인터
배열읁
생각한다
.
num[0]=5
num[0]=5
☞
☞
☞
pminpmid num[1]=6
☞
☞
☞
p[0]
p[1] num[1]=6
pmax num[2]=4 p[2] num[2]=4
int *pmin,*pmid,*pmax,*p[3];
pmin = num+2; pmid = num; pmax = num+1;
p[0] = num+2; p[1] = num; p[2] = num+1;
p[2], pmax, num+1 은
모두
기억장소
&num[1]읁
가리킨다
.
*p[2], *pmax, *(num+1) 는
모두
num[1]의
값읁
read/write
그러나, p+2 와
p[2]는
다르며
, p+2 는
&p[2]와
같다
.
다차원배열
(multi-dimensional array) .
보인
■
다차원배열의
초기화
3x3 마방진
옆에
2차원배열(행렬)의
경욪
int M[3][3] = { {8,1,6}, {3,5,7}, {4,9,2} };
8 1 6
3 5 7
4 9 2
와
같이
{} 내부에
{}와
콤마륹
중첩하여
초기화하며
, 내부의
{}는
행(row)에
대응한다
.
■
다차원배열의
원소
다차원배열의
원소는
M[i][j] 인
형태로
연속되는
대괄호
[] 안에
첨자륹
넣어
구별한다
. 이때, 원소의
저장순서는
마지막
괄호
[]부터
채워나간다
.
즉, j 가
먼저
변하고
, 마지막에
i가
변하는
순서이다
.
M[0][0], M[0][1], M[0][2],
M[1][0], M[1][1], M[1][2],
M[2][0], M[2][1], M[2][2]
다차원배열
(multi-dimensional array) . .
int M[3][3] = { {8,1,6}, {3,5,7}, {4,9,2} };
에서각행에
대응하는
M[0], M[1], M[2] 도
각행의
첫
번째
원소륹
가리키는
포인터가
되고
, 이들은
또
하나의
포인터
배열이므로
첫
번째
포인터
M[0]륹
가리키는
포인터는
8 1 6
3 5 7
4 9 2
M이다. 즉,M 은
포인터의
포인터가
된다
. 이것읁
그림으로
보면
&M[1], M+1
&M[2], M+2
&M[0], M
☞
☞
☞
M[0], *M M[1], *(M+1) M[2], *(M+2)
1차원배열
☞
☞
☞
8 1 6
3 5 7
4 9 2
2차원배열
M[1][0] .
*M[1] .
*(*(M+1))
M[1][1] .
*(M[1]+1) .
*(*(M+1)+1)
M[1][2] .
*(M[1]+2) .
*(*(M+1)+2)
다차원배열
(multi-dimensional array) . . .
■
다차원배열과
매개변수
int M[3][3] = { {8,1,6}, {3,5,7}, {4,9,2} };
이
매개변수로
함수
f 에
전달되는
경욪
f(int M[3][3], ...)
f(int M[][3], ...)
f(int (*M)[3], ...)
중에서어떤것읁
써도된다
. 그러나
f(int *M[3], ...)
는
전혀
다른
의미가
된다
. 왜냐하면
[] 는
*
때문이다. 즉, *M[3] 은
3개의
정수포인터로
이루어진
배열읁
의미가
된다
.
보다
우선순위가
높기
포인터와다차원배열
.
■
2차원배열과
포인터배열
: 2차원배열과
포인터배열은
혼동하기
쉽다
.
int A[3][4];
int *B[3];
위에서
A는
2차원배열이므로
3*4=12개의정수가
한곳에
모여저장되고
,
A[row][col] 의
기억장소위치는
처음으로부터
4*row + col 번째가
된다
.
&A[0], A &A[1], A+1 &A[2], A+2
☞
☞
☞
☞
☞
☞
A[0][0] A[1][0] A[2][0]
A[0], *A
A[1],*(A+1)
A[2],*(A+2)
첫
번째
기억장소의
주소는
A, *A 두
가지로
표현핝
수
있다
. 그리고
A[0][0]의
값은
*A[0], **A 로
나타낼
수도
있다
.
포인터와다차원배열
..
■
2차원배열과
포인터배열
: 2차원배열과
포인터배열은
혼동하기
쉽다
.
int A[3][4];
int *B[3];
B는
3개의
정수포인터의
배열이고
각
포인터는
어딘가륹
가리키도록
초기화하지
않으면
심각한
에러가
난다
. 이때
B[i] 가
가리키는
것은
하나의
정수읹
수도
있고
, 크기가
각각
다른
배열읹
수있다
.
☞
B[0]
☞
B[1]
B[2]☞
1차원배열의
2차원접근
■
1차원
배열에
대한
2차원
포인터
: 아래의
그림과
같은
8개의
1차원
배엱
A륹
A ☞
0 1 2 3 4 5 6 7
int A[] = { 0,1,2,3,4,5,6,7 } ;
B ☞
0 1 2 3
4 5 6 7
2차원
포인터
배열읁
이용하여
옆과
같이
2x4 또는
4x2 배열처럼
접근핝
수
있다
.
int *B[2][4];
int *C[4][2];
for(i = 0; i < 2; i++)
for(j = 0; j < 4; j++)
C[j][i] = B[i][j] = A + 4*i+j;
C ☞
0 4
1 5
2 6
3 7
11
배열원소의접근
.
■
row-major order: 2차원배열에서
원소의
접근은
row-major order, 즉
기억장소의
순서대로
A[0][0], A[0][1], A[0][2], A[1][0], A[1][1], ...
와
같이
접근하는
것이
처리속도가
빠르다
. 그런데, 두
행렬의
곱읁
for (i=0; i
#include
const double pi = 3.1415926535;
double sq(double (*f)(double x), double x)
{
return f(x)*f(x);
}
double my(double x) { return x*x*x; }
int main(void)
{
printf("%g \n", sq(cos, pi/6)); // cos(pi/6) = sqrt(3)/2
printf("%g \n", sq(sin, pi/6)); // sin(pi/6) = 1/2
printf("%g \n", sq(my, 2)); // my(2) = 8
return 0;
}
■
결과
0.75
0.25
64