언어 공부/C++

포인터-2

세희홍 2022. 6. 22. 13:15

배열

int main() {
	int arr[5];
	int* parr = &arr[3];

	cout << parr << " " << &arr[3] << endl; // FA10 FA10
	parr++;
	cout << parr << " " << &arr[4] << endl; // FA14 FA14

	return 0;
}

배열 포인터에 +1을 하면 주소에 4bytes(int)가 더해진다. arr[3] -> arr[4]

 

int main() {
	int arr[5] = { 1, 2, 3, 4, 5 };
	int* parr = arr; // &arr[0];

	for (int k = 0; k < sizeof(arr) / sizeof(arr[2]); k++) {
		cout << arr + k << endl; // F758 F75C F760 F764 F768
		cout << parr + k << endl; // F758 F75C F760 F764 F768
		cout << &arr[k] << endl; // F758 F75C F760 F764 F768
		cout << &parr[k] << endl; // F758 F75C F760 F764 F768
		cout << *(parr + k) << endl; // 1, 2, 3, 4, 5
		cout << *(arr + k) << endl; // 1, 2, 3, 4, 5 배열명을 포인터 같이 사용
		cout << parr[k] << endl; // 1, 2, 3, 4, 5 포인터를 배열과 같이 사용 
	}
	return 0;
}

 

#include <iostream>
using namespace std;

int getSum(const int*, int);  // 프로토타입

int main()
{
  // 배열 선언과 초기화
  int arr[5] = {10, 11, 12, 13, 14};
  // 함수 호출
  cout << "요소의 합: " << getSum(arr, 5);
  return 0;
}

int getSum(const int* p, int size)
{
  int sum = 0;
  for(int i = 0; i < size ; i++)
  {
    sum += *(p++);
  }
  return sum;
}

 

 

배열 포인터

int main() {
	int arr[5] = { 1, 2, 3, 4, 5 };
	int (*p)[5] = &arr;

	(*p)[2] = 7;

	cout << arr[2] << endl; // 7
	return 0;
}

포인터가 배열 전체를 가리키고 특정 위치의 값을에 접근. 

 

 

포인터 배열

 

배열 안의 원소들이 포인터. 

int main() {
	int x = 1, y = 2, z = 3;

	int* parr[3];
	parr[0] = &x;
	parr[1] = &y;
	parr[2] = &z;

	cout << &y << parr[1]  << *(parr[1]); //FB14 FB14 2

	return 0;
}

 

 

이중 포인터

int main() {
	int x = 1;
	int* px = &x;
	int** ppx = &px;
	cout << **ppx << endl; // 1
	cout << *ppx << px << &x; // F858 F858 F858 

	return 0;
}

 

 

클래스를 포인터로 가리키기

 

int main() {
	Friend a, b, c; // 객체 3개 생성
	a.phone = 1;
	a.p = &b;
	b.phone = 2;
	b.p = &c;
	c.phone = 3;
	c.p = &a;

	cout << a.phone << a.p->phone << a.p->p->phone << a.p->p->p->phone;
	// 1 2 3 1
	return 0;
}

p는 포인터이므로 Friend 클래스 타입의 객체 주소를 받을 수 있다. 

a는 b의 주소를, b는 c의 주소를, c는 a의 주소를 가진다. 

 


# 배열 요소의 합 구하기

#include <iostream>
using namespace std;

int getSum(const int*, int);

int main()
{
    int arr[5] = { 10, 11, 12, 13, 14 };
    cout << "요소의 합: " << getSum(arr, 5);
    return 0;
}

int getSum(const int* p, int size)
{
    int sum = 0;
    for (int i = 0; i < size; i++)
    {
        sum += *(p++);
    }
    return sum;
}

 

 

# 배열 요소를 거꾸로 만들기

#include <iostream>
using namespace std;

void reverse(int*, int);

int main()
{
    int arr[5] = { 10, 11, 12, 13, 14 };
    reverse(arr, 5);
    cout << "배열 거꾸로 출력: ";
    for (int i = 0; i < 5; i++)
    {
        cout << *(arr + i) << "   ";
    }
    return 0;
}

void reverse(int* pArr, int size)
{
    int i = 0;
    int j = size - 1;
    while (i < size / 2)
    {
        int temp = *(pArr + i);
        *(pArr + i) = *(pArr + j);
        *(pArr + j) = temp;
        i++;
        j--;
    }
}

return by reference

 

# fraction.h

#include <iostream>
using namespace std;

#ifndef FRACTION_H
#define FRACTION_H

class Fraction
{
    // 데이터 멤버
private:
    int numer;
    int denom;

    // public 멤버 함수  
public:
    // 생성자
    Fraction(int num, int den);
    Fraction();
    Fraction(const Fraction& fract);
    ~Fraction();
    // 접근자  
    int getNumer() const;
    int getDenom() const;
    void print() const;
    // 설정자
    void setNumer(int num);
    void setDenom(int den);

    // private 보조 멤버 함수
private:
    void normalize();
    int gcd(int n, int m);
};
#endif

# fraction.cpp

#include <iostream>
#include <cmath>
#include <cassert>
#include "fraction.h"
using namespace std;

Fraction::Fraction(int num, int den = 1)
    : numer(num), denom(den)
{
    normalize();
}

Fraction::Fraction()
    : numer(0), denom(1)
{
}

Fraction::Fraction(const Fraction& fract)
    : numer(fract.numer), denom(fract.denom)
{
}

Fraction::~Fraction()
{
}

int Fraction::getNumer() const
{
    return numer;
}

int Fraction::getDenom() const
{
    return denom;
}

void Fraction::print() const
{
    cout << numer << "/" << denom << endl;
}

void Fraction::setNumer(int num)
{
    numer = num;
    normalize();
}

void Fraction::setDenom(int den)
{
    denom = den;
    normalize();
}

void Fraction::normalize() // 약분
{
    // 분모가 0인 경우
    if (denom == 0)
    {
        cout << "잘못된 분모 값입니다. 프로그램을 중단합니다." << endl;
        assert(false);
    }
    // 분모와 분자의 부호 변경
    if (denom < 0)
    {
        denom = -denom;
        numer = -numer;
    }
    // 최대 공약수로 분자와 분모 나누기
    int divisor = gcd(abs(numer), abs(denom));
    numer = numer / divisor;
    denom = denom / divisor;
}

int Fraction::gcd(int n, int m) // 최대공약수
{
    int gcd = 1;
    for (int k = 1; k <= n && k <= m; k++)
    {
        if (n % k == 0 && m % k == 0)
        {
            gcd = k;
        }
    }
    return gcd;
}

 

# app.cpp

#include "fraction.h" 

Fraction& larger(Fraction&, Fraction&);  // 프로토타입

int main()
{
    Fraction fract1(3, 13);
    Fraction fract2(5, 17);
    cout << "첫 번째 쌍에서 더 큰 분수: ";
    larger(fract1, fract2).print();
    Fraction fract3(4, 9);
    Fraction fract4(1, 6);
    cout << "두 번째 쌍에서 더 큰 분수: ";
    larger(fract3, fract4).print();
    return 0;
}

Fraction& larger(Fraction& fract1, Fraction& fract2) //레퍼런스를 통한 리턴. 오버헤드 줄이기
{
    if (fract1.getNumer() * fract2.getDenom() >
        fract2.getNumer() * fract1.getDenom())
    {
        return fract1;
    }
    return fract2;
}