함수 오버로딩
오버로딩이란 여러 함수들이 동일한 이름을 사용할 수 있는 기능을 말한다. 어떤 함수들이 이름은 똑같으면서 인자의 종류(시그니처)만 다르다면 이 함수들은 오버로드되었다고 말한다. 오버로딩을 사용함으로써 인자의 종류에 상관 없이 동일한 코드를 사용할 수 있다.
 기본적인 오버로딩 규칙
1. 컴퓨터는 인자의 타입을 확인해서 그에 가장 잘 어울리는 시그니처를 가진 함수를 호출하게 된다.
2. 반환 값만 틀린 경우는 오버로드 할 수 없다.
3. 시그니처가 다르더라도 오버로드 할 수 없는 경우
   void SameSignature(int i);
   void SameSignature(int& r);
 적당한 함수를 찾는 순서
1. 정확하게 일치하는 경우(Exact Match)
2. 승진에 의한 형변환(Promotion)
3. 표준 형변환(Standard Conversions)
4. 사용자에 의한 형변환(User-defined Conversions

   // 함수 오버로딩을 보여주는 예제
#include <iostream>
using namespace std;

void function(void)
{
  cout << "Function(void) call" << endl;
}

int function(char c)
{
  cout << "Function(char c) call" << endl;
}

void function(int a, int b)
{
  cout << "Function(int a, int b) call" << endl;
}

int main()
{
  function();  // void function(void) 함수 호출
  function('a');  // int fuction(char c) 함수 호출
  function(1213);  // void function(int a, int b) 함수 호출

  return 0;
}
 


 디폴트 인자
디폴트 인자는 우리가 따로 값을 지정해주지 않은 경우에 선택하는 인자의 값을 말한다. 디폴트 인자의 경우에는 함수를 호출 할 때 해당 인자의 값을 적어주지 않아도 된다.
  // 디폴트 인자를 보여주는 예제
#include <iostream>
using namespace std;

int boxvolume(int length, int width = 1int height = 1);

int main()
{
  cout << "[3, 3, 3]  : " << boxvolume(333<< endl;
  cout << "[5, 5, def]  : " << boxvolume(55<< endl;
  cout << "[7, def, def]  : " << boxvolume(7<< endl;

  return 0;
}

int boxvolume(int length, int width, int height)
{
  return length * width * height;
}


   동적할당
동적 메모리 할당은 말 그대로 메모리를 동적으로 할당한다는 뜻이다. 메모리의 크기를 프로그램이 실행되는 도중에 동적으로 결정하여 할당하며, 메모리를 할당하고 해제하는 시점이 자유롭다. 단, 동적 메모리 할당으로 할당한 메모리는 사용자가 직접 해제해주기 전까지는 절대로 컴퓨터에 위해서 해제되는 일이 없으므로 신경써서 해제해주지 않으면 메모리 누수가 일어난다.

 연산자 new, delete, new[], delete[]

new, delete는 변수 하나를 동적으로 할당하는 것이고 new[], delete[]는 배열을 동적으로 할당할 때 사용한다.
  // 동적 할당 예제
#include <iostream>
using namespace std;

int main()
{
  int size;

  cout << "할당하고자 하는 배열의 크기";
  cin >> size;

  int *arr = new int[size];

  for(int i = 0 ; i < size ; i++)
  {
    arr[i] = i + 10;
  }
  for(int j = 0 ; j < size ; j++)
  {
    cout << "arr[" << j << "] = " << arr[j] << endl;
  }
  delete[] arr;

  return 0;
}


 동적 메모리 할당과 관련된 기본적인 규칙
1. new, delete와 new[], delete[] 쌍을 맞춰서 사용하자.
2. NULL 포인터를 해제하는 것은 안전하다.
3. 해제한 메모리를 또 해제해서는 안 된다.
  // 할당 받은 메모리를 해제할 때..
#include <iostream>
using namespace std;

int main()
{
  // 메모리를 할당한다.
  short *p = new short[100];

  cout << "p = " << p << endl;
  delete[] p;
  p = NULL;

  cout << "p = " << p << endl;
  delete[] p;
  p = NULL;

  return 0;
}
// 할당 받은 메모리를 해제 할 때, 그 공간은 더 이상 유효하지 않으므로 그 공간을 가리키는 포인터 변수를 NULL로 초기화 함으로써 더 신뢰성 있는 코드를 작성할 수 있다.

 동적 할당 내부 동작

기본적으로 c프로그램의 메모리 구조는 다음과 같다. 동적할당을 하게 되면 Heap영역에 메모리가 할당된다.
Stack : 지역변수
Heap : 동적할당
bss : 초기화 되지 않은 전역변수 or static변수
Data : 초기화 된 전역변수 or static변수
일반적으로 각 영역에는 다음과 같은 변수들이 할당된다.

   문자열
문자열은 문자형 배열이다. 문자형 상수는 작은따옴표를 이용하여 표시하고, 문자열 상수는 큰 따옴표로 표시한다. 문자열은 컴파일러에 의해 자동적으로 맨 마지막에 NULL 문자('\0')가 들어간다.
  // 문자열 길이를 알아보는 프로그램
#include <stdio.h>
#include <string.h>

int main()
{
  int length;
  int size;

  length = strlen("string");
  size = sizeof("string");

  printf("string length : %d\n", length);
  printf("string size : %d\n", size);
  
  return 0;
}

// strlen()함수는 정확히 문자열 길이를 출력해준다. sizeof는 변수의 메모리 공간 크기를 나타낸다.

  // strlen()함수를 직접 만들어봄
#include <stdio.h>

int strlen2(const char *p);

int main()
{
  int iNum;

  iNum = strlen2("test");
  printf("iNum = %d\n", iNum);

  return 0;
}

int strlen2(const char *p)
{
  int iCnt;

  for(iCnt = 0 ; *p != 0 ; iCnt++)
  {
    ++p;  // 포인터 위치를 한 칸씩 뒤로 옮김
  }

  return iCnt;
}


  // 문자열 함수를 이용하는 프로그램
#include <stdio.h>
#include <string.h>

int main()
{
  char stringA[80= "everywhere people stare ";
  char stringB[80= "every and each day";
  char stringC[80= "";

  char ch = '\0';
  char *pch = &ch;

  printf("stringA : %s\n", stringA);
  printf("length of stringA : %d\n", strlen(stringA));

  // stringA 와 stringB의 비교
  printf("compare string: %d\n", strcmp(stringA, stringB));
  printf("compare string: %d\n", strncmp(stringA, stringB, 5));
  
  // stringC 에 stringA 복사
  strcpy(stringC, stringA);
  printf("stringC : %s\n", stringC);
  printf("stringC : %s\n\n", strncpy(stringC, stringB, 10));

  // stringA에 stingB 붙이기
  strcat(stringA, stringB);
  printf("%s\n\n", stringA);

  // 문자열에서 'y'문자 검색
  printf("stringB : %s\n", stringB);
  pch = strchr(stringB, 'y');
  if(pch == NULL)
  {
    printf("Not exist\n");
  }
  else
  {
    printf("'y' position %d from head\n", pch - stringB);
  }

  pch = strrchr(stringB, 'y');
  if(pch == NULL)
  {
    printf("Not exist\n");
  }
  else
  {
    printf("'y' position %d from tail\n", pch - stringB);
  }
  return 0;
}

+ Recent posts