The C++ Programming Language - 기본 문법

an_yan_yang·2025년 2월 4일

본 글을 개인적 학습을 위한 글입니다. 틀린 내용이 있을 시 마구 지적해주시면 감사합니다.

기초

이 글은 C언어를 마스터한 사람을 기준으로 작성 되었기 때문에, 당연하게 받아들여지는 문법들에 대해서는 따로 짚고 넘어가지 않습니다.

  • 연산자
  • 조건문
  • 반복문
  • 배열
  • 함수 등은 모두 기본적으로 C와 동일하다.

아래는 주의 사항 및 짚고 넘어가야 할 부분에 대한 설명들이다.

함수 원형, 함수 프로토타입(prototype)

: 변수 선언처럼, 함수의 형식만 선언한 것

→ 선언하는 이유

함수 이름, 매개 변수 타입과 개수, 리턴 타입을 컴파일러에게 알려주어 함수 호출 문장이 정확한지 판단할 수 있도록 도움을 줄 수 있음


매개 변수로 배열 전달 시

1차원 배열은 ‘pointer’ 그대로 전달 혹은 arr[]의 형태로 전달한다.

하지만 2차원 이상의 배열부터는 첫 번째 인덱스를 제외한 나머지 인덱스를 알려주어야 한다.

→ 이는 정적 배열일 때만 해당되고, 사용 역시 제한적입니다. 정해진 형식의 매개변수만을 받을 수 있는 보수적인 함수가 생성되기 때문이라고 할 수 있다.

주의 사항

  2차원 배열을 사용할 때 분명히, 정적인 방법이 아닌 동적 할당을 이용할 수 있습니다. 하지만 2차원 배열과 Double 포인터(이중)는 엄연히 다른 개념입니다. 따라서 인자로 넘겨줄 때에는 가능한 1차원 배열의 형태로 넘겨주는 것이 가장 적절하다.

void function(int * arr , ..){
	for(int i=0;i<row;i++){
		for(int j=0;j<col;j++){
			int idx = i + j;
			arr[idx] = i + j;
			...
}

int main(void){
	int matrix[3][5];
		function(matrix[0]); // 첫 번째 주소를 넘겨준다.
		...
}

포인터

포인터는 실행 중 메모리의 주소 값(이를 이용하여 직접 값을 쓰거나 값을 읽어올 수 있음)

실행 전에는 변수가 메모리 몇 번지에 기록되는 지 알 수 없다.

프로그램이 실행될 때, 변수의 절대 메모리 주소가 정해지기 때문이다.



C++ 문자열

  • C-String 방식 : ‘\0’으로 끝나는 문자배열
  • String 클래스 : 다양한 멤버 함수 제공 (문자열 비교, 복사, 수정 등)

C-String으로 문자열 다루기

  • C언어에서 사용한 함수 사용 가능

    strcmp(), strlen(), strcpy() 등

  • <cstring> (권장)이나 <string.h> 라이브러리를 include 하여 사용


cin.getline()을 통한 문자열 입력

  • 기본적으로 cin을 통한 입력은 공백이 없어야 하기에 공백을 포함하는 문자열은 cin.getline()을 통해 입력 받아야 한다.
cin.getline(char buff[], int size, char delimitChar);
// buff에 최대 size-1개의 문자 입력 ('\0' 존재)
// delimitChar를 만나면 입력 중단 (Default는 '\n')

C++에서 문자열을 다루는 string 클래스

  • C++에서 강력 추천
  • C++ 표준 클래스
  • 문자열의 크기에 따른 제약 없음 (스스로 내부 버퍼 조절)
  • 문자열 복사, 비교, 수정 등을 위한 다양한 함수와 연산자 제공
  • 객체 지향적
  • <string> 헤더 파일에 선언
  • C-string보다 다루기 쉬움
  • C-String과 다르게 string 클래스의 문자열은 대입 연산자 사용이 가능하다.
    • 첨언. C-String은 선언 시에만 대입 연산자 사용이 가능하다.

공백이 있는 string을 받기 위한 방법은?

전역 함수 getline()을 이용하면 공백이 있는 string 타입의 문자열을 입력 받을 수 있다.


주의 사항

만일 “Sejong”과 같은 문자열 자체를 함수로 보내거나 또는 그러한 경우에 함수의 인자는 아래와 같이 작성되어야 한다. 그렇지 않다면 컴파일 오류가 발생할 수 있다.

void function(const char *str){ }

  또한 함수 속에서 “Sejong”을 변환하려고 해도 이미 박혀있는(const) 데이터이기에 다른 값을 대입해도 바뀌지 않는다. 즉, ReadOnly라 할 수 있다. 이때 “Sejong”과 같은 데이터를 “Literal(리터럴)”이라 한다.
어떻게 보면 이것이 C-String의 문제라고 할 수 있는데, C++의 string class를 이용하여 인자로 주고 받으면 문제가 발생하지 않는다. 여기서 문제라 함은 컴파일 오류 가능성이나 데이터를 변환하는 작업, 가공하는 작업 등에 문제가 발생할 수 있음을 의미한다. literal을 string 인자로 받게 되면 새로운 string 객체가 생성된다. 이는 메모리에 존재하는 literal과 별개의 메모리이므로 literal을 다음과 같이 받기를 권장한다.

void function(string str){ }

잡지식

int main(int argc, char **argv)

main 함수, 이는 Program Entry Point라고도 불린다. 프로그램이 시작되는 시작 포인트라는 것이다.

main함수가 없더라도 컴파일은 가능하다. 하지만 실행이 되지 않는다. 이 실행이 되지 않는 소스 코드를 라이브러리라고도 한다.


전역 변수와 지역 변수

만일, 전역 변수와 지역 변수를 동일한 이름으로 선언하고 연산하면, 컴파일러는 가장 최근에 선언된 변수를 기준으로 연산한다. (물론 사용해서는 안 된다.)


스택 메모리와 힙 메모리

함수는 스택 메모리에 저장된다.

→ 함수에 인자를 준다는 것은 미리 메모리를 저장한다는 것이다.(변수를 선언한다는 것, 단 Call-By-Reference는 제외)

void mySwap(int a, int b)}
	int p = a;
	int q = b;
} 
	// 함수 종료 후에 선언된 변수 p, q에 대한 메모리는 해제된다.

연속 선상에서 지역 변수도 스택 메모리로 본다.


하지만 전역 변수는 다르다.

전역 변수는 힙(heap) 메모리이다. 그렇기에 우스갯 소리로 Stack-overflow가 발생하면 지역 변수를 전역 변수로 선언하는 것이 가장 간단한 방법이라는 말도 있다. 스택 메모리가 힙 메모리에 비해 아주 작기 때문이다. 하지만, 동적 할당도 힙 메모리에 변수를 지정하는 것이기에 동적 할당하는 것을 가장 추천하고 있다.


잡 지식은 가능하다면 나중에 추가적으로 더 다루어볼 예정입니다. 다음 글은 C++에 추가된 핵심 기능인 클래스에 대해서 알아보겠습니다.


참고 자료

profile
개발자가 되고 싶은 공대생

0개의 댓글