본문 바로가기
c++

3주차-포인터

by 몰라몰라개복치 2020. 4. 3.

모든 데이터들은 메모리 상에 특정한 공간에 저장. 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

http://tcpschool.com/cpp/cpp_function_basic