모든 데이터들은 메모리 상에 특정한 공간에 저장. int 형 변수를 정의한다면 4바이트이므로 메모리 상의 4칸을 차지/ 프로그램 작동 시 컴퓨터는 각 메모리에 있는 데이터를 필요하게 됨. 서로 구분하기 위해 각 메모리에 고유의 주소를 붙임
만약 int형 변수 a에 10이라는 값을 넣어 준다 가정
=>고유의 주소값(ex: 0x152839)라는 위치부터 4바이트의 공간을 차지하며 10이라는 값이 저장
이때 포인터란 특정한 데이터가 저장된 주소값을 보관하는 변수
포인터
(1). 포인터의 기본 개념
- 포인터 선언: *을 붙여준다
- 포인터 변수 p에는 변수의 주소가 들어감
즉, char형 변수는 문자를 저장, int형 변수는 정수를 저장, 포인터는 주소값을 저장하는 것
int n=100; //변수의 선언
int *ptr=&n; //포인터의 선언
=> 이와 같이 포인터 변수에는 꼭 주소값을 넣어야 함
변수 이름 앞에 '&'를 붙여서 사용함으로써 주소값 출력 가능
이때 배열의 이름은 그 자체가 주소이므로 '&'을 붙이지 않음
ex)
int a[10];
int *p;
p=a; //배열인 경우
int a;
int *p;
p=&a //변수인 경우
포인터가 가리키는 곳의 실제값을 구하려면 '*'을 붙인다
- 포인터 변수 p가 a가 들어있는 주소인 100번지를 가리킨다고 가정!
int a=123;
int *p;
p=&a;
printf("%d", p); // a의 주소인 100 출력
printf("%d", *p); // p가 가리키는 곳의 실제값 즉 a값 출력
포인터는 동시 선언 가능
int *ptr1, *ptr2; (O)
int *ptr1, ptr2; (X)
포인터의 덧셈, 뺄셈
int형 포인터에 1을 더해 준 결과 두 수 차이가 4인 것을 확인했다 다른 변수의 값도 살펴 본 결과
4바이트를 차지하는 int형 포인터에 +1을 해준 값으론 4바이트가 늘어났고
8바이트를 차지하는 double 형 포인터에 +1을 더해준 값으론 8바이트가 늘어난 것을 확인
따라서 포인트에 덧셈을 한 결과 +(더해준 값)*(데이타의 '형' 의 크기) 만큼의 주소값이 출력
(빼기로 변환하면 마이너스 결과 처리)
BUT, 포인터와 포인터끼리의 덧셈 뺄셈은 불가능
배열과 포인터
배열들의 각 원소는 메모리 상에 연속되게 놓이게 됨
이때 한개의 원소가 int 형의 변수이기 떄문에 4바이트씩 차지. 이를 아래의 코드를 통해서 배열들의 각 원소가 연속적으로 4바이트(데이타의 '형' 의 크기)씩 차지한다는 것을 확인 가능.
예시)
앞서 포인터에서 1을 더하면 데이터의 형의 크기만큼 값이 증가하는 것을 확인
=>배열의 시작 부분을 가리키는 포인터를 정의한 뒤에 포인터에 1 을 더하면 그 다음 원소를 가리키고 그리고 2 를 더한 그 다음 다음 원소를 가리킨다는 것을 유추 가능
이해가 안 된다면 다음의 코드를 통해 이해해 보자.
=> parr 이 int 형이므로 + i 를 하면 주소값에는 사실상 4*i 가 더해지게 된다. 이때 arr[i] 의 주소값도 i 가 하나씩 커질 때 마다 4 씩 증가하므로 (int 형 배열이므로) 결과적으로 모든 결과가 일치
포인터에 정수를 더하는 것 만으로도 배열의 각 원소를 가리킬 수 있다. 즉 * 를 이용하여 원소들과 똑같은 역할을 할 수 있게 됨. (이때 배열 이름만 입력할 시엔 첫 번째 원소를 가리킴)
즉, arr[i] 와 같은 문장은 사실 컴파일러에 의해 *(arr + i) 로 변환
이제 본격적으로 포인터로 배열을 가리켜 보자
포인터로 1차원 배열 가리키기
이때 arr를 parr에 대입하는 부분을 자세하게 보자 앞에서 말했듯이 arr 과 같이 배열의 이름만 입력할 시엔 배열의 첫번째 원소를 가리키는 포인터로 변환
즉,
parr=arr;
parr=&arr[0]
과 동일한 문장
따라서, parr 을 통해서 arr 을 이용했을 때와 동일하게 배열의 원소에 마음껏 접근할 수 있게 되는 것
ex 1차원 배열을 포인터로 접근한 예시)
함수
함수(function)란 하나의 특별한 목적의 작업을 수행하기 위해 독립적으로 설계된 코드의 집합. C++ 프로그램에서 함수는 특정 작업을 캡슐화하는데 유용하게 사용
<함수를 사용하는 이유>
- 바로 반복적인 프로그래밍을 피할 수 있기 때문(프로그램이 필요할 때마다 작성한 함수를 호출하면 해당 작업을 반복해서 수행 가능)
- 전체적인 코드의 가독성 향상
함수의 선언
1. 반환 타입(return type) : 함수가 모든 작업을 마치고 반환하는 데이터의 타입을 명시
2. 함수 이름 : 함수를 호출하기 위한 이름을 명시
3. 매개변수 목록(parameters) : 함수 호출 시에 전달되는 인수의 값을 저장할 변수들을 명시
4. 함수 몸체 : 함수의 고유 기능을 수행하는 명령문의 집합
<함수의 선언 순서>
C++ 에서 함수를 정의할 때는 그 순서가 매우 중요
EX) 인수로 전달받은 두 수 중에서 더 작은 수를 반환하는 SmallNum() 함수를 사용한 예시
#include <iostream>
using namespace std;
int SmallNum(int num1, int num2)
{
if (num1 <= num2)
{
return num1;
}
else
{
return num2;
}
}
int main(void)
{
int result;
result = SmallNum(4, 6);
cout << " 두 수 중 더 작은 수는 " << result << "입니다." << endl;
result = SmallNum(8, 6);
cout << " 두 수 중 더 작은 수는 " << result << "입니다." << endl;
result = SmallNum(2, 8);
cout << " 두 수 중 더 작은 수는 " << result << "입니다." << endl;
return 0;
}
->위의 예제는 함수를 선언해준 뒤에 함수를 호출하므로 문제 없이 실행된다
이때 함수의 선언 순서를 바꿔보자
#include <iostream>
using namespace std;
int main(void)
{
int result;
result = SmallNum(4, 6);
cout << " 두 수 중 더 작은 수는 " << result << "입니다." << endl;
result = SmallNum(8, 6);
cout << " 두 수 중 더 작은 수는 " << result << "입니다." << endl;
result = SmallNum(2, 8);
cout << " 두 수 중 더 작은 수는 " << result << "입니다." << endl;
return 0;
}
int SmallNum(int num1, int num2)
{
if (num1 <= num2)
{
return num1;
}
else
{
return num2;
}
}
위의 예제에서 컴파일러는 main()함수에 등장하는 SmallNum() 함수를 아직 알지 못하기 떄문에 컴파일 오류 발생. 따라서 컴파일러에 SmallNum() 함수는 나중에 정의되어 있다고 알려주는 단계 필요.
=> 이것이 함수의 원형을 선언하는 것
함수의 원형 선언 방식
반환타입 SmallNum(매개변수목록);
다음 예제는 앞서 살펴본 예제에 함수의 원형 선언을 추가한 예제.
이처럼 함수의 원형은 main() 함수 앞에 미리 선언되어야 함
#include <iostream>
using namespace std;
int SmallNum(int, int);
int main(void)
{
int result;
result = SmallNum(4, 6);
cout << " 두 수 중 더 작은 수는 " << result << "입니다." << endl;
result = SmallNum(8, 6);
cout << " 두 수 중 더 작은 수는 " << result << "입니다." << endl;
result = SmallNum(2, 8);
cout << " 두 수 중 더 작은 수는 " << result << "입니다." << endl;
return 0;
}
int SmallNum(int num1, int num2)
{
if (num1 <= num2)
{
return num1;
}
else
{
return num2;
}
}
=>컴파일 오류 발생 X 정상적으로 컴파일 실행
참고:https://modoocode.com/231#page-heading-17
씹어먹는 C 언어 시작하기
안녕하세요 여러분. 씹어먹는 C 언어를 연재하고 있는 Psi 입니다.제 강좌는 제가 참고했던 무수히 많은 책, 인터넷을 돌아다니며 얻은 지식, 그리고 제 경험에서 우러나온 모든 것을 잘 버무려서 만든 것이기 때문에, C 언어를 사용할 줄 아시는 분들이라도, 한 번쯤은 훑어 보시는 것을 추천합니다. 강좌를 한 번 다 읽었다면 내가 뭘 배웠는지 머리속으로 그려본다. 만약 위 과정이 잘 되지 않는다면 다시 한 번 강좌를 읽는다. 만약 강좌가 이해가 안되면 혼자
modoocode.com
https://modoocode.com/231#page-heading-18
씹어먹는 C 언어 시작하기
안녕하세요 여러분. 씹어먹는 C 언어를 연재하고 있는 Psi 입니다.제 강좌는 제가 참고했던 무수히 많은 책, 인터넷을 돌아다니며 얻은 지식, 그리고 제 경험에서 우러나온 모든 것을 잘 버무려서 만든 것이기 때문에, C 언어를 사용할 줄 아시는 분들이라도, 한 번쯤은 훑어 보시는 것을 추천합니다. 강좌를 한 번 다 읽었다면 내가 뭘 배웠는지 머리속으로 그려본다. 만약 위 과정이 잘 되지 않는다면 다시 한 번 강좌를 읽는다. 만약 강좌가 이해가 안되면 혼자
modoocode.com
'c++' 카테고리의 다른 글
6주차-객체 배열, 동적 메모리 할당, 객체 배열 동적 생성, this 포인터 (0) | 2020.06.08 |
---|---|
5주차 - 접근 지정자, 인라인 함수, 헤더, 객체 포인터 (0) | 2020.05.31 |
c++ 2주차(조건문, 반복문, 배열) (0) | 2020.04.01 |
C++ 1단원, 2단원 + 입출력 + 연산자 (0) | 2020.03.25 |