SlideShare una empresa de Scribd logo
1 de 35
C언어와 포인터 (3)
포인터 학습
"완전학습을 지향하는" NHN NEXT 정호영
나눔고딕 및 나눔고딕코딩 글꼴을 설치해 주세요.
오늘의 토픽
1. 함수에 배열을 건네주기
2. 2차원 배열과 포인터
3. 문자열과 포인터
4. 구조체와 포인터
0. TIP
짧은 팁:
(*&) 또는 (&*) 는 상쇄되어 사라집니다.
int main(void) {
int a = 4;
int *p = &a;
printf("%d %dn", *&a, a);
printf("%p %pn", &*p, p);
}
이중 포인터 다시 보기
int x = 10;
int *ptr = &x;
int **pptr = &ptr;
이중 포인터 다시 보기
/
- *는 연속해서 올 수 있지만 &는 안 됩니다.
- 이것보다는 그림이 더 명확합니다.
int x = 10;
int *ptr = &x;
int **pptr = &ptr;
/*
1) pptr = &ptr, ptr = &x
2) pptr = &ptr = &&x (아님)
2) *pptr = *(&ptr) = ptr
3) **pptr = **(&ptr) = *ptr = *(&x) = x = 10
*/
배열과 포인터의 차이점
arr = &arr[0] = &*(arr +0) = arr 입니다.
이 때 arr 은 읽기 전용입니다!
int arr[] = {0, 1, 2, 3, 4};
int *ptr = arr;
ptr = ptr + 1; //ok, *ptr = 1;
arr = arr + 1; //error
1. 함수에 배열을 건네주기
예제)
크기가 n인 int 배열에 0 ~ n – 1 까지
값을 초기화하는 함수를 작성하고 테스트하시오.
예제)
크기가 n인 int 배열에 0 ~ n – 1 까지
값을 초기화하는 함수를 작성하고 테스트하시오.
void setArray(int array[], int n) {
}
int main(void) {
int arr[10];
setArray(arr, 10);
for( int i = 0; i < 10; i++)
printf(“%dn”, arr[i]);
return 0;
}
배열과 포인터는 다릅니다.
int *a; 와
int a[]; 는
서로 다른 문장인데
딱 한 경우에는 완전히 같습니다.
언제?
int *a; 와 int a[]; 는 서로 다른 문장이지만
parameter 안에서는 같습니다.
void foo(int *a)
= void foo(int a[])
= void foo(int a[10])
마지막 줄의 숫자는 아무 의미가 없습니다. 무시됩니다.
1차원 배열은 배열이 아니라 포인터로 넘겨주기 때문에
1) 자동으로 Call by Reference가 된다.
2) 배열의 크기를 알 수 없다.
2의 이유로 C언어에서는 배열의 크기를
반드시 따로 전달해야 합니다.
예제)
크기가 n인 배열에 0 ~ n – 1 까지
값을 초기화하는 함수를 작성하고 테스트하시오.
예제)
크기가 n인 int 배열에 0 ~ n – 1 까지
값을 초기화하는 함수를 작성하고 테스트하시오.
void setArray(int *array, int n) {
for( int i = 0; i < n; i++)
array[i] = i;
}
int main(void) {
int arr[10];
setArray(arr, 10);
for( int i = 0; i < 10; i++)
printf(“%dn”, arr[i]);
return 0;
}
예제)
크기가 n인 배열을 동적 할당으로 생성하고
0 ~ n – 1 까지 값을 초기화하는 함수를
작성하고 테스트하시오.
예제)
크기가 n인 배열을 동적 할당으로 생성하고
0 ~ n – 1 까지 값을 초기화하는 함수를
작성하고 테스트하시오.
*array[i] 라고 하면 어떻게 될까요?
void setArray(int **array, int n) {
*array = calloc(n, sizeof(int));
for( int i = 0; i < n; i++)
(*array)[i] = i;
}
int main(void) {
int *ptr;
setArray(&ptr, 10);
for( int i = 0; i < 10; i++)
printf(“%dn”, (*ptr)[i]);
return 0;
}
2. 2차원 배열과 포인터
1.메모리는 1차원인데 2차원 배열을 어떻게 저장할까요?
왜 00, 01, 02, 10, 11, 12 순서로 접근할까요?
00, 10, 01, 11, 02, 12 순서도 상관없지 않나요?
int arr[2][3] = { { 0, 1, 2 }, { 3, 4, 5 } };
int main(void) {
int arr[2][3] = { { 0, 1, 2 },
{ 3, 4, 5 } };
for (int i = 0; i < 2; i++)
for (int j = 0; j < 3; j++)
printf("%pn", &arr[i][j]);
}
arr[m][n] 배열을 1차원 포인터로 캐스팅하면
arr[m][n]; //m * n 배열
int *ptr = (int *) arr;
라면…
arr[i][j]
= *(ptr + i * n + j)
예제) 2차원 배열과 단일 포인터
int main(void) {
int arr[2][3] = { { 0, 1, 2 },
{ 3, 4, 5 } };
// int *ptr = arr; warning!!
int *ptr = (int *) arr;
for (int i = 0; i < 2; i++){
for (int j = 0; j < 3; j++) {
printf("%d ", *(ptr + i * 3 + j));
}
printf("n");
}
}
앞의 예제에서 알 수 있는 것처럼
이차원 배열과 단일 포인터는 서로 다른 타입입니다.
그럼 이차원 배열의 이름은 어떤 타입의 주소일까요?
int
조금 복잡하지만
-ptr 변수는 int 3개짜리 배열의 포인터입니다.
-이차원 배열은 1차원 배열의 배열이다.
int arr[2][3] = { { 0, 1, 2 }, { 3, 4, 5 } };
int (*ptr)[3] = arr; //ok
예제) 2차원 배열과 배열의 포인터
int main(void) {
int arr[2][3] = { { 0, 1, 2 }, { 3, 4, 5 } };
for (int i = 0; i < 2; i++){
for (int j = 0; j < 3; j++) {
printf("%d ", *(*(arr + i) + j));
}
printf("n");
}
}
arr[i][j]
= (*(arr+ i))[j]
= *(*(arr +i) + j)
원리는 이런데 쓸모는 없습니다.
함수로 이차원 배열을 전달하려면
1. 단일 포인터로 캐스팅해서 전달 또는
2. 배열의 포인터로 전달
두 가지 방법이 있습니다.
예제)
n * 5 이차원 배열을
엣지있게 출력하는 함수를 작성하세요.
void print2d_arr(int(*arr)[5], int w) {
for (int i = 0; i < w; i++){
for (int j = 0; j < 5; j++) {
printf("%d ", arr[i][j]);
}
printf("n");
}
}
int main(void) {
int arr[3][5] =
{ { 0, 1, 2, 3, 4 }, { 5, 6, 7 }, { 8, 9 } };
print2d_arr(arr, 3);
}
3. 문자열과 포인터
문자열은 그냥 문자의 1차원 배열이예요.
int main(void) {
char a[] = “Hello, world”;
printf(“%sn”, a);
return 0;
}
문자열의 끝은 null 문자(0) 으로 끝나야 합니다.
int main(void) {
char a[20];
//a = “Hi”; //wrong
//a[0] = “H”; //wrong
a[0] = ‘H’;
a[1] = ‘i’;
a[2] = ‘0’;
printf(“%sn”, a);
}
문자열 관련 함수
문자열을 복사하는 함수: strcpy()
문자열을 이어주는 함수: strcat()
문자열을 개수를 세는 함수: strlen()
다양한 함수가 있습니다.
예제)
문자열을 복사하기 위해 필요한 공간만큼
동적 할당을 하고 복사를 하는 함수를 만들어 봅시다.
int strcpy(char **src, const char *str);
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#pragma warning(disable:4996)
void mystrcpy(char **src, const char* str) {
*src = calloc(sizeof(char), strlen(str) + 1);
strcpy(*src, str);
}
int main(void) {
char *s;
mystrcpy(&s, "Hello");
printf("%sn", s);
}
아래 두 개는 어떤 차이일까요?
문자열이 가변 길이이므로 위처럼 포인터의 배열의 되어
야 합니다.
아래는 에러입니다.
char *strings[3] = { “Hello”, “world”, “Hoo” };
char (*strings)[10] = { “Hello”, “world”, “Hoo”}; //error
구조체와 구조체의 포인터는 동영상 강의를 참고하세요.
스탠포드에서 제작한 포인터와 메모리 / 링크드 리스트 문
서를 읽으면 도움이 많이 됩니다.
Thank You

Más contenido relacionado

La actualidad más candente

Python3 10장 문자열이야기
Python3 10장 문자열이야기Python3 10장 문자열이야기
Python3 10장 문자열이야기
Jihoon Kong
 
Erlang을 이용한 swap 서버
Erlang을 이용한 swap 서버Erlang을 이용한 swap 서버
Erlang을 이용한 swap 서버
Jaejin Yun
 
6장 표현식 및 문장
6장 표현식 및 문장6장 표현식 및 문장
6장 표현식 및 문장
재정 이
 
2012 Ds D2 03
2012 Ds D2 032012 Ds D2 03
2012 Ds D2 03
chl132435
 
2012 Ds D2 03 Pdf
2012 Ds D2 03 Pdf2012 Ds D2 03 Pdf
2012 Ds D2 03 Pdf
kd19h
 
포인터와 배열
포인터와 배열포인터와 배열
포인터와 배열
Kim YoSep
 

La actualidad más candente (20)

9. pointer
9. pointer9. pointer
9. pointer
 
Python3 10장 문자열이야기
Python3 10장 문자열이야기Python3 10장 문자열이야기
Python3 10장 문자열이야기
 
Erlang
ErlangErlang
Erlang
 
Erlang을 이용한 swap 서버
Erlang을 이용한 swap 서버Erlang을 이용한 swap 서버
Erlang을 이용한 swap 서버
 
Regex
RegexRegex
Regex
 
6장 표현식 및 문장
6장 표현식 및 문장6장 표현식 및 문장
6장 표현식 및 문장
 
2012 Ds D2 03
2012 Ds D2 032012 Ds D2 03
2012 Ds D2 03
 
Java standard(8~13)
Java standard(8~13)Java standard(8~13)
Java standard(8~13)
 
[170529 6주차]C언어 A반
[170529 6주차]C언어 A반[170529 6주차]C언어 A반
[170529 6주차]C언어 A반
 
2012 Ds D2 03 Pdf
2012 Ds D2 03 Pdf2012 Ds D2 03 Pdf
2012 Ds D2 03 Pdf
 
What’s new in c++11
What’s new in c++11What’s new in c++11
What’s new in c++11
 
Study1
Study1Study1
Study1
 
정규표현식(Regular expressions)
정규표현식(Regular expressions)정규표현식(Regular expressions)
정규표현식(Regular expressions)
 
배열과 포인터
배열과 포인터배열과 포인터
배열과 포인터
 
C++11
C++11C++11
C++11
 
5주차 스터디
5주차 스터디5주차 스터디
5주차 스터디
 
Python3 brief summary
Python3 brief summaryPython3 brief summary
Python3 brief summary
 
C Language For Arduino
C Language For ArduinoC Language For Arduino
C Language For Arduino
 
파이썬 숫자,변수,문자열
파이썬 숫자,변수,문자열파이썬 숫자,변수,문자열
파이썬 숫자,변수,문자열
 
포인터와 배열
포인터와 배열포인터와 배열
포인터와 배열
 

Destacado

포인터의 공식
포인터의 공식포인터의 공식
포인터의 공식
Hoyoung Jung
 
[네트워크] TCP, 믿을 수 있나요!?
[네트워크] TCP, 믿을 수 있나요!?[네트워크] TCP, 믿을 수 있나요!?
[네트워크] TCP, 믿을 수 있나요!?
용민 박
 
뇌자T 1.네트워크와 tcpip
뇌자T   1.네트워크와 tcpip뇌자T   1.네트워크와 tcpip
뇌자T 1.네트워크와 tcpip
sj k
 
패킷의 전달과정
패킷의 전달과정패킷의 전달과정
패킷의 전달과정
성연 김
 

Destacado (20)

포인터의 공식
포인터의 공식포인터의 공식
포인터의 공식
 
Memory & object pooling
Memory & object poolingMemory & object pooling
Memory & object pooling
 
TCP/IP Protocol - JAVA
TCP/IP Protocol - JAVATCP/IP Protocol - JAVA
TCP/IP Protocol - JAVA
 
Database
DatabaseDatabase
Database
 
네트워크 스터디(Tcp 소켓 프로그래밍)
네트워크 스터디(Tcp 소켓 프로그래밍)네트워크 스터디(Tcp 소켓 프로그래밍)
네트워크 스터디(Tcp 소켓 프로그래밍)
 
[네트워크] TCP, 믿을 수 있나요!?
[네트워크] TCP, 믿을 수 있나요!?[네트워크] TCP, 믿을 수 있나요!?
[네트워크] TCP, 믿을 수 있나요!?
 
뇌자T 1.네트워크와 tcpip
뇌자T   1.네트워크와 tcpip뇌자T   1.네트워크와 tcpip
뇌자T 1.네트워크와 tcpip
 
Haskell study 15
Haskell study 15Haskell study 15
Haskell study 15
 
Multi thread
Multi threadMulti thread
Multi thread
 
[14.10.20] 아! 그거...모르겠습니다 - TLS(devrookie)
[14.10.20] 아! 그거...모르겠습니다 - TLS(devrookie)[14.10.20] 아! 그거...모르겠습니다 - TLS(devrookie)
[14.10.20] 아! 그거...모르겠습니다 - TLS(devrookie)
 
Tcp ip & io model
Tcp ip & io modelTcp ip & io model
Tcp ip & io model
 
TOAST Meetup2015 - 구름 Cloud IDE (류성태)
TOAST Meetup2015 - 구름 Cloud IDE (류성태)TOAST Meetup2015 - 구름 Cloud IDE (류성태)
TOAST Meetup2015 - 구름 Cloud IDE (류성태)
 
파이썬 데이터 검색
파이썬 데이터 검색파이썬 데이터 검색
파이썬 데이터 검색
 
내 질문에는 왜 답변이 달리지 않을까
내 질문에는 왜 답변이 달리지 않을까내 질문에는 왜 답변이 달리지 않을까
내 질문에는 왜 답변이 달리지 않을까
 
소프트웨어 개발자를 위한 하드웨어 상식
소프트웨어 개발자를 위한 하드웨어 상식소프트웨어 개발자를 위한 하드웨어 상식
소프트웨어 개발자를 위한 하드웨어 상식
 
Sync async-blocking-nonblocking-io
Sync async-blocking-nonblocking-ioSync async-blocking-nonblocking-io
Sync async-blocking-nonblocking-io
 
Next 게임 실전 프로젝트 슬라이드
Next 게임 실전 프로젝트 슬라이드Next 게임 실전 프로젝트 슬라이드
Next 게임 실전 프로젝트 슬라이드
 
[D2 CAMPUS]웹 개발자의 스펙 : HTTP
[D2 CAMPUS]웹 개발자의 스펙 : HTTP[D2 CAMPUS]웹 개발자의 스펙 : HTTP
[D2 CAMPUS]웹 개발자의 스펙 : HTTP
 
Effective c++chapter8
Effective c++chapter8Effective c++chapter8
Effective c++chapter8
 
패킷의 전달과정
패킷의 전달과정패킷의 전달과정
패킷의 전달과정
 

Similar a 3.포인터

2012 Ds B1 01
2012 Ds B1 012012 Ds B1 01
2012 Ds B1 01
seonhyung
 
Cpp 0x kimRyungee
Cpp 0x kimRyungeeCpp 0x kimRyungee
Cpp 0x kimRyungee
scor7910
 
2012 Ds A1 05
2012 Ds A1 052012 Ds A1 05
2012 Ds A1 05
seonhyung
 
자료구조 그래프 보고서
자료구조 그래프 보고서자료구조 그래프 보고서
자료구조 그래프 보고서
mil23
 
빠르게 활용하는 파이썬3 스터디(ch1~4)
빠르게 활용하는 파이썬3 스터디(ch1~4)빠르게 활용하는 파이썬3 스터디(ch1~4)
빠르게 활용하는 파이썬3 스터디(ch1~4)
SeongHyun Ahn
 
11. array & pointer
11. array & pointer11. array & pointer
11. array & pointer
웅식 전
 
가능한 C++ 스타일의 캐스트를 즐겨 쓰자
가능한 C++ 스타일의 캐스트를 즐겨 쓰자가능한 C++ 스타일의 캐스트를 즐겨 쓰자
가능한 C++ 스타일의 캐스트를 즐겨 쓰자
민욱 이
 
2012 Dm A0 04 Pdf
2012 Dm A0 04 Pdf2012 Dm A0 04 Pdf
2012 Dm A0 04 Pdf
kd19h
 
2012 Dm A0 04 Pdf
2012 Dm A0 04 Pdf2012 Dm A0 04 Pdf
2012 Dm A0 04 Pdf
jinwookhong
 
2012 Dm A0 02 Pdf
2012 Dm A0 02 Pdf2012 Dm A0 02 Pdf
2012 Dm A0 02 Pdf
kd19h
 
2012 Dm A0 02 Pdf
2012 Dm A0 02 Pdf2012 Dm A0 02 Pdf
2012 Dm A0 02 Pdf
jinwookhong
 

Similar a 3.포인터 (20)

2012 Ds B1 01
2012 Ds B1 012012 Ds B1 01
2012 Ds B1 01
 
Cpp 0x kimRyungee
Cpp 0x kimRyungeeCpp 0x kimRyungee
Cpp 0x kimRyungee
 
2015 Kitel C 언어 강좌3
2015 Kitel C 언어 강좌32015 Kitel C 언어 강좌3
2015 Kitel C 언어 강좌3
 
2012 Ds A1 05
2012 Ds A1 052012 Ds A1 05
2012 Ds A1 05
 
자료구조 그래프 보고서
자료구조 그래프 보고서자료구조 그래프 보고서
자료구조 그래프 보고서
 
빠르게 활용하는 파이썬3 스터디(ch1~4)
빠르게 활용하는 파이썬3 스터디(ch1~4)빠르게 활용하는 파이썬3 스터디(ch1~4)
빠르게 활용하는 파이썬3 스터디(ch1~4)
 
11. array & pointer
11. array & pointer11. array & pointer
11. array & pointer
 
가능한 C++ 스타일의 캐스트를 즐겨 쓰자
가능한 C++ 스타일의 캐스트를 즐겨 쓰자가능한 C++ 스타일의 캐스트를 즐겨 쓰자
가능한 C++ 스타일의 캐스트를 즐겨 쓰자
 
이산수학03
이산수학03이산수학03
이산수학03
 
스칼라와 스파크 영혼의 듀오
스칼라와 스파크 영혼의 듀오스칼라와 스파크 영혼의 듀오
스칼라와 스파크 영혼의 듀오
 
2012 Dm A0 04 Pdf
2012 Dm A0 04 Pdf2012 Dm A0 04 Pdf
2012 Dm A0 04 Pdf
 
2012 Dm A0 04 Pdf
2012 Dm A0 04 Pdf2012 Dm A0 04 Pdf
2012 Dm A0 04 Pdf
 
코딩인카페 C&JAVA 기초과정 C프로그래밍(3)
코딩인카페 C&JAVA 기초과정 C프로그래밍(3)코딩인카페 C&JAVA 기초과정 C프로그래밍(3)
코딩인카페 C&JAVA 기초과정 C프로그래밍(3)
 
2012 Dm A0 02 Pdf
2012 Dm A0 02 Pdf2012 Dm A0 02 Pdf
2012 Dm A0 02 Pdf
 
2012 Dm A0 02 Pdf
2012 Dm A0 02 Pdf2012 Dm A0 02 Pdf
2012 Dm A0 02 Pdf
 
이산치2번
이산치2번이산치2번
이산치2번
 
(닷넷, C#기초교육)C#선택적인수, 명명된 인수
(닷넷, C#기초교육)C#선택적인수, 명명된 인수(닷넷, C#기초교육)C#선택적인수, 명명된 인수
(닷넷, C#기초교육)C#선택적인수, 명명된 인수
 
자료구조 프로젝트
자료구조 프로젝트자료구조 프로젝트
자료구조 프로젝트
 
불어오는 변화의 바람, From c++98 to c++11, 14
불어오는 변화의 바람, From c++98 to c++11, 14 불어오는 변화의 바람, From c++98 to c++11, 14
불어오는 변화의 바람, From c++98 to c++11, 14
 
HI-ARC PS 101
HI-ARC PS 101HI-ARC PS 101
HI-ARC PS 101
 

Más de Hoyoung Jung

Más de Hoyoung Jung (20)

철권 1단에서 벗어나기
철권 1단에서 벗어나기철권 1단에서 벗어나기
철권 1단에서 벗어나기
 
코딩 공부 시작하기
코딩 공부 시작하기코딩 공부 시작하기
코딩 공부 시작하기
 
entry를 이용한 코딩 교육1
entry를 이용한 코딩 교육1entry를 이용한 코딩 교육1
entry를 이용한 코딩 교육1
 
Github Markdown
Github MarkdownGithub Markdown
Github Markdown
 
stored procedure2 + jdbc
stored procedure2 + jdbcstored procedure2 + jdbc
stored procedure2 + jdbc
 
mysql stored procedure
mysql stored proceduremysql stored procedure
mysql stored procedure
 
암달의 법칙과 쿼리튜닝 기초
암달의 법칙과 쿼리튜닝 기초암달의 법칙과 쿼리튜닝 기초
암달의 법칙과 쿼리튜닝 기초
 
mysql 서브쿼리
mysql 서브쿼리mysql 서브쿼리
mysql 서브쿼리
 
GROUP BY, CASE WHEN
GROUP BY, CASE WHENGROUP BY, CASE WHEN
GROUP BY, CASE WHEN
 
트랜잭션
트랜잭션 트랜잭션
트랜잭션
 
데이터베이스 정규화
데이터베이스 정규화데이터베이스 정규화
데이터베이스 정규화
 
MySQL 인덱스의 기초
MySQL 인덱스의 기초MySQL 인덱스의 기초
MySQL 인덱스의 기초
 
tomcat jdbc mysql 프로그래밍
tomcat jdbc mysql 프로그래밍tomcat jdbc mysql 프로그래밍
tomcat jdbc mysql 프로그래밍
 
MySQL JOIN
MySQL JOINMySQL JOIN
MySQL JOIN
 
데이터베이스 모델링
데이터베이스 모델링데이터베이스 모델링
데이터베이스 모델링
 
MySQL delete.update
MySQL delete.updateMySQL delete.update
MySQL delete.update
 
MySQL Select (1)
MySQL Select (1)MySQL Select (1)
MySQL Select (1)
 
2. MySQL DataTye Basic
2. MySQL DataTye Basic2. MySQL DataTye Basic
2. MySQL DataTye Basic
 
MySQL Create Table
MySQL Create TableMySQL Create Table
MySQL Create Table
 
Mymysql basic sql
Mymysql basic sqlMymysql basic sql
Mymysql basic sql
 

3.포인터

  • 1. C언어와 포인터 (3) 포인터 학습 "완전학습을 지향하는" NHN NEXT 정호영 나눔고딕 및 나눔고딕코딩 글꼴을 설치해 주세요.
  • 2. 오늘의 토픽 1. 함수에 배열을 건네주기 2. 2차원 배열과 포인터 3. 문자열과 포인터 4. 구조체와 포인터
  • 4. 짧은 팁: (*&) 또는 (&*) 는 상쇄되어 사라집니다. int main(void) { int a = 4; int *p = &a; printf("%d %dn", *&a, a); printf("%p %pn", &*p, p); }
  • 5. 이중 포인터 다시 보기 int x = 10; int *ptr = &x; int **pptr = &ptr;
  • 6. 이중 포인터 다시 보기 / - *는 연속해서 올 수 있지만 &는 안 됩니다. - 이것보다는 그림이 더 명확합니다. int x = 10; int *ptr = &x; int **pptr = &ptr; /* 1) pptr = &ptr, ptr = &x 2) pptr = &ptr = &&x (아님) 2) *pptr = *(&ptr) = ptr 3) **pptr = **(&ptr) = *ptr = *(&x) = x = 10 */
  • 7. 배열과 포인터의 차이점 arr = &arr[0] = &*(arr +0) = arr 입니다. 이 때 arr 은 읽기 전용입니다! int arr[] = {0, 1, 2, 3, 4}; int *ptr = arr; ptr = ptr + 1; //ok, *ptr = 1; arr = arr + 1; //error
  • 8. 1. 함수에 배열을 건네주기
  • 9. 예제) 크기가 n인 int 배열에 0 ~ n – 1 까지 값을 초기화하는 함수를 작성하고 테스트하시오.
  • 10. 예제) 크기가 n인 int 배열에 0 ~ n – 1 까지 값을 초기화하는 함수를 작성하고 테스트하시오. void setArray(int array[], int n) { } int main(void) { int arr[10]; setArray(arr, 10); for( int i = 0; i < 10; i++) printf(“%dn”, arr[i]); return 0; }
  • 11. 배열과 포인터는 다릅니다. int *a; 와 int a[]; 는 서로 다른 문장인데 딱 한 경우에는 완전히 같습니다. 언제?
  • 12. int *a; 와 int a[]; 는 서로 다른 문장이지만 parameter 안에서는 같습니다. void foo(int *a) = void foo(int a[]) = void foo(int a[10]) 마지막 줄의 숫자는 아무 의미가 없습니다. 무시됩니다.
  • 13. 1차원 배열은 배열이 아니라 포인터로 넘겨주기 때문에 1) 자동으로 Call by Reference가 된다. 2) 배열의 크기를 알 수 없다. 2의 이유로 C언어에서는 배열의 크기를 반드시 따로 전달해야 합니다.
  • 14. 예제) 크기가 n인 배열에 0 ~ n – 1 까지 값을 초기화하는 함수를 작성하고 테스트하시오.
  • 15. 예제) 크기가 n인 int 배열에 0 ~ n – 1 까지 값을 초기화하는 함수를 작성하고 테스트하시오. void setArray(int *array, int n) { for( int i = 0; i < n; i++) array[i] = i; } int main(void) { int arr[10]; setArray(arr, 10); for( int i = 0; i < 10; i++) printf(“%dn”, arr[i]); return 0; }
  • 16. 예제) 크기가 n인 배열을 동적 할당으로 생성하고 0 ~ n – 1 까지 값을 초기화하는 함수를 작성하고 테스트하시오.
  • 17. 예제) 크기가 n인 배열을 동적 할당으로 생성하고 0 ~ n – 1 까지 값을 초기화하는 함수를 작성하고 테스트하시오. *array[i] 라고 하면 어떻게 될까요? void setArray(int **array, int n) { *array = calloc(n, sizeof(int)); for( int i = 0; i < n; i++) (*array)[i] = i; } int main(void) { int *ptr; setArray(&ptr, 10); for( int i = 0; i < 10; i++) printf(“%dn”, (*ptr)[i]); return 0; }
  • 18. 2. 2차원 배열과 포인터
  • 19. 1.메모리는 1차원인데 2차원 배열을 어떻게 저장할까요? 왜 00, 01, 02, 10, 11, 12 순서로 접근할까요? 00, 10, 01, 11, 02, 12 순서도 상관없지 않나요? int arr[2][3] = { { 0, 1, 2 }, { 3, 4, 5 } }; int main(void) { int arr[2][3] = { { 0, 1, 2 }, { 3, 4, 5 } }; for (int i = 0; i < 2; i++) for (int j = 0; j < 3; j++) printf("%pn", &arr[i][j]); }
  • 20. arr[m][n] 배열을 1차원 포인터로 캐스팅하면 arr[m][n]; //m * n 배열 int *ptr = (int *) arr; 라면… arr[i][j] = *(ptr + i * n + j)
  • 21. 예제) 2차원 배열과 단일 포인터 int main(void) { int arr[2][3] = { { 0, 1, 2 }, { 3, 4, 5 } }; // int *ptr = arr; warning!! int *ptr = (int *) arr; for (int i = 0; i < 2; i++){ for (int j = 0; j < 3; j++) { printf("%d ", *(ptr + i * 3 + j)); } printf("n"); } }
  • 22. 앞의 예제에서 알 수 있는 것처럼 이차원 배열과 단일 포인터는 서로 다른 타입입니다. 그럼 이차원 배열의 이름은 어떤 타입의 주소일까요? int 조금 복잡하지만 -ptr 변수는 int 3개짜리 배열의 포인터입니다. -이차원 배열은 1차원 배열의 배열이다. int arr[2][3] = { { 0, 1, 2 }, { 3, 4, 5 } }; int (*ptr)[3] = arr; //ok
  • 23. 예제) 2차원 배열과 배열의 포인터 int main(void) { int arr[2][3] = { { 0, 1, 2 }, { 3, 4, 5 } }; for (int i = 0; i < 2; i++){ for (int j = 0; j < 3; j++) { printf("%d ", *(*(arr + i) + j)); } printf("n"); } }
  • 24. arr[i][j] = (*(arr+ i))[j] = *(*(arr +i) + j) 원리는 이런데 쓸모는 없습니다.
  • 25. 함수로 이차원 배열을 전달하려면 1. 단일 포인터로 캐스팅해서 전달 또는 2. 배열의 포인터로 전달 두 가지 방법이 있습니다.
  • 26. 예제) n * 5 이차원 배열을 엣지있게 출력하는 함수를 작성하세요. void print2d_arr(int(*arr)[5], int w) { for (int i = 0; i < w; i++){ for (int j = 0; j < 5; j++) { printf("%d ", arr[i][j]); } printf("n"); } } int main(void) { int arr[3][5] = { { 0, 1, 2, 3, 4 }, { 5, 6, 7 }, { 8, 9 } }; print2d_arr(arr, 3); }
  • 28. 문자열은 그냥 문자의 1차원 배열이예요. int main(void) { char a[] = “Hello, world”; printf(“%sn”, a); return 0; }
  • 29. 문자열의 끝은 null 문자(0) 으로 끝나야 합니다. int main(void) { char a[20]; //a = “Hi”; //wrong //a[0] = “H”; //wrong a[0] = ‘H’; a[1] = ‘i’; a[2] = ‘0’; printf(“%sn”, a); }
  • 30. 문자열 관련 함수 문자열을 복사하는 함수: strcpy() 문자열을 이어주는 함수: strcat() 문자열을 개수를 세는 함수: strlen() 다양한 함수가 있습니다.
  • 31. 예제) 문자열을 복사하기 위해 필요한 공간만큼 동적 할당을 하고 복사를 하는 함수를 만들어 봅시다. int strcpy(char **src, const char *str);
  • 32. #include <stdio.h> #include <stdlib.h> #include <string.h> #pragma warning(disable:4996) void mystrcpy(char **src, const char* str) { *src = calloc(sizeof(char), strlen(str) + 1); strcpy(*src, str); } int main(void) { char *s; mystrcpy(&s, "Hello"); printf("%sn", s); }
  • 33. 아래 두 개는 어떤 차이일까요? 문자열이 가변 길이이므로 위처럼 포인터의 배열의 되어 야 합니다. 아래는 에러입니다. char *strings[3] = { “Hello”, “world”, “Hoo” }; char (*strings)[10] = { “Hello”, “world”, “Hoo”}; //error
  • 34. 구조체와 구조체의 포인터는 동영상 강의를 참고하세요. 스탠포드에서 제작한 포인터와 메모리 / 링크드 리스트 문 서를 읽으면 도움이 많이 됩니다.