C++, 7. 함수

이도현·2023년 11월 7일
0

1. 값에 의한 전달

  • 아래 코드를 통해 주소를 확인함으로써 변수명이 같아도 함수가 다르면 주소가 다름을 확인할 수 있다.
void doSomething(int y)
{
  cout <<"int func " << y << " " << &y << endl;
}

int main()
{
  doSomething(5);

  int x = 6;

  cout << "In main" << x << " " << &x << endl;

  doSomething(x);
  doSomething(x + 1);

  return 0;
}

2. 참조에 의한 인수 전달

  • 참조를 매개변수로 사용한 함수는 다른 곳에 썻을 때 주소가 남는다.
void addOne(int &y)
{
  y = y + 1
}

int main()
{
  int x = 5;

  cout << x << " ' << &x << endl;

  addOne(x);

  cout << x << " " << &x << endl;
}

3. 주소에 의한 전달

  • 외부에 있는 변수의 값을 집정 변경할 수 있다.
void foo(int *ptr)
{
	cout << *ptr << " " << ptr << " " << &ptr << endl;
}

int main()
{
  int value = 5;

  cout << value << " " << &value << endl;

  int *ptr = &value;

  foo(value);
  foo(&value);

  return 0;
}

4. Tuple

  • 서로 다른 타입의 값을 가질 수 있는 고정된 값의 컨테이너
std::tuple<int, double> getTuple()
{
  int a = 10;
  double d = 3.14;

  return std::make tuple(a, d);
}

int main()
{
  //std::tuple<int, double> my_tp = getTuple();
  //cout << std::get<0>(my_tp) << endl; //a
  //cout << std::get<1>(my_tp) << endl; //d
  //C++17이후
  auto[a, d] = getTuple();
  cout << a << endl;
  cout << d << endl;

  return 0;
}

5. 함수 오버로딩

  • 같은 이름의 함수
int add(int x, int y)
{
  return x + y;
}

double add(double x, double y)
{
  return x + y;
}

int main()
{
  add(1, 2);
  add(3.0, 4.0);//함수명이 같아도 타입을 알아서 식별하여 컴파일 해준다.)
}
  • 함수도 주고 값을 가진다.
// 함수 포인터
int func()
{
  reuturn  4;
}

int main()
{
  cout << func << endl; // 주소가 나오므로 함수도 포인터라는 증거

  return 0;
}

6. vector new-delete 대체

int main()
{
  std::vector<int> v {1, 2, 3};

  v.reserve(1024); //new delete보다 속도 빠름

  //for (auto &e : v)
  for(unsigned int i = 0; i < v.size(); ++i)
    cout << v[i] << " ";
  cout << endl;

  cout << v.size() << " " << v.capacity() << endl;

  int *ptr = v.data();

  cout << ptr[2] << endl; //v.resize(2);를 했을 경우 3이 사라진 것이 아닌 숨겨진 것이란 반증

7. stack

  • vector를 활용하여 스택처럼 사용
void printStack(const std::vector<int> &stack)
{
  for (auto &e : stack)
    cout << e << " ";
  cout << endl;
}

int main()
{
  std::vector<int> stack;

  //stack.resrve(1024);

  stack.push_back(3);
  printStack(stack);

  stack.push_back(5);
  printStack(stack);

  stack.push_back(7);
  printStack(stack);

  stack.pop_back();
  printStack(stack);

  stack.pop_back();
  printStack(stack);

  stack.pop_back();
  printStack(stack);
}

8. 재귀적 함수

  • 종료조건이 반드시 필요
void countDown(int count)
{
  cout << count << endl;

  if(count > 0)
     countDown(count - 1);
}

int main()
{
  countDown(5);

9. assert 단언하기(dubug 모드에서만 작동됨)

  • 오류가 어디서 났는지 알려준다.
#include <cassert> //assert.h
#include <array>
void printValue(const std::array<int, 5> &my_array, const int& ix)
{
  assert(ix >= 0);
  assert(ix <= my_array.size() - 1);

  std:: cout << my_array[ix] << std::endl;
}

int main()
{
  std::array<int, 5> my_array{1, 2, 3, 4, 5}

  printValue(my_array, 100)// 100의 크기를 만들 수 없다는 오류가 어디서 났는지 assert로 단언함으로써 위치를 알려준다.)

  return 0;  
}

10. Ellipsis

  • 매개변수 작성을 생략할 수 있다.
double findAverage(int count, ...)// 갯수에 제한은 없지만 타입은 정해주어야함.
{
  double sum = 0;

  va_list list:

  va_start(list, count);

  for(int arg = 0; arg < count; ++arg)
    sum += va_arg(list,int);

  va_end(list);

  return sum / count;
}

int main()
{
  cout << findAverage(1, 1,  2, 3, "Hello", "c") << endl;
  cout << findAverage( 3, 1, 4, 5) << endl;
  cout << findAverage(5, 4, ,5, 3, ,2, 4) << endl;
  cout << findAverage(10, 1, 3, 4, 5, 3) << endl;

  return 0;
}
profile
좋은 지식 나누어요

0개의 댓글