C와 C++는 서로 밀접한 관계가 있는 언어지만, 프로그래밍 패러다임과 문법에서 큰 차이가 있습니다.
이 장에서는 C와 C++의 주요 차이점을 살펴보겠습니다.
2.1 C와 C++의 기본 차이
📌 C 언어
✅ 절차적 프로그래밍(Procedural Programming) 언어
✅ 데이터와 함수를 분리해서 작성
✅ 변수 선언 및 정의 방식이 제한적
✅ 함수 포인터 기반의 동적 호출 구조
📌 C++ 언어
✅ 객체지향 프로그래밍(Object-Oriented Programming, OOP) 언어
✅ 데이터와 함수를 클래스로 묶어 캡슐화
✅ 메모리 관리 기능 (new/delete, 스마트 포인터)
✅ 가상 함수 (Virtual Function) 기반의 다형성 (Polymorphism) 제공
✅ 템플릿, 연산자 오버로딩 등 추가적인 기능 제공
항목 | C | C++ |
패러다임 | 절차적 프로그래밍 | 객체지향 프로그래밍 (OOP) |
변수 선언 위치 | 함수의 최상단에서만 가능 | 중간 선언 가능 |
메모리 관리 | malloc/free 사용 | new/delete 및 스마트 포인터 |
함수 오버로딩 | 지원하지 않음 | 지원 |
네임스페이스 | 없음 | 있음 (namespace) |
객체지향 프로그래밍 | 지원하지 않음 | 지원 |
템플릿 (제네릭 프로그래밍) | 지원하지 않음 | 지원 (template) |
2.2 변수 선언 방식의 차이
C에서는 변수 선언이 함수의 최상단에서만 가능(내가 학부 때는 이렇게 배웠다. 하지만 C를 쓴다면 여전히 이걸 고수하는 분들이 있음 )
하지만, C++에서는 필요한 위치에서 선언이 가능합니다.
📌 C 코드 (함수의 최상단에서만 선언 가능)
#include <stdio.h>
void func() {
int a = 10; // ✅ 허용
printf("%d\n", a);
}
📌 C++ 코드 (어디서든 변수 선언 가능)
#include <iostream>
void func() {
int a = 10; // ✅ 정상
std::cout << a << std::endl;
int b = a * 2; // ✅ 중간 선언도 가능
std::cout << b << std::endl;
}
2.3 auto 키워드의 도입
C++에서는 auto 키워드를 사용해 변수 타입을 자동으로 결정할 수 있습니다.
이는 C++11부터 추가된 기능이며, 특히 템플릿 코드에서 유용합니다.
📌 C++의 auto 키워드 사용 예시
#include <iostream>
int main() {
auto x = 10; // x는 int 타입
auto y = 3.14; // y는 double 타입
auto z = "Hello"; // z는 const char* 타입
std::cout << x << " " << y << " " << z << std::endl;
}
📌 정리:
- C에서는 변수 타입을 반드시 명시적으로 선언해야 하지만,
- C++에서는 auto를 사용해 자동으로 타입을 추론할 수 있음.
2.4 메모리 할당 방식의 차이
C와 C++ 모두 동적 메모리 할당을 지원하지만,
C++에서는 new와 delete를 사용하며, 스마트 포인터(shared_ptr, unique_ptr)도 추가되었습니다.
📌 C 스타일 (malloc/free 사용)
#include <stdio.h>
#include <stdlib.h>
int main() {
int *p = (int*)malloc(sizeof(int)); // 동적 할당
*p = 42;
printf("%d\n", *p);
free(p); // 메모리 해제
return 0;
}
📌 C++ 스타일 (new/delete 사용)
#include <iostream>
int main() {
int *p = new int(42); // 동적 할당
std::cout << *p << std::endl;
delete p; // 메모리 해제
return 0;
}
📌 C++의 스마트 포인터 (메모리 자동 관리)
#include <iostream>
#include <memory> // 스마트 포인터 사용
int main() {
std::shared_ptr<int> p = std::make_shared<int>(42); // 자동 메모리 관리
std::cout << *p << std::endl; // delete 필요 없음!
}
📌 정리:
- C에서는 malloc/free를 사용, 타입 캐스팅 필요
- C++에서는 new/delete를 사용, 타입 캐스팅 불필요
- C++11 이후에는 스마트 포인터 (shared_ptr, unique_ptr)를 권장
2.5 참조자 (Reference)와 포인터
C++에서는 참조자(Reference)를 도입하여 포인터보다 더 편리한 방식으로 메모리를 다룰 수 있습니다.
📌 C 스타일 (포인터)
#include <stdio.h>
void change(int *p) {
*p = 20; // 포인터를 사용하여 값 변경
}
int main() {
int a = 10;
change(&a); // 주소 전달
printf("%d\n", a); // 출력: 20
}
📌 C++ 스타일 (참조자)
#include <iostream>
void change(int &r) { // 참조자로 전달
r = 20; // 직접 값 변경 가능
}
int main() {
int a = 10;
change(a); // 참조를 통해 값 변경
std::cout << a << std::endl; // 출력: 20
}
📌 정리:
- C에서는 포인터(*p)를 사용해 값을 변경하지만,
- C++에서는 참조자(&r)를 사용하면 가독성이 좋아지고 더 직관적인 코드 작성 가능
2.6 네임스페이스 (Namespace)
C++에서는 이름 충돌을 방지하기 위해 네임스페이스를 사용할 수 있습니다.
C에는 네임스페이스 개념이 없기 때문에 전역 변수 충돌이 발생할 위험이 큽니다.
📌 C 스타일 (전역 변수 충돌 위험)
#include <stdio.h>
int value = 10; // 전역 변수
void printValue() {
printf("%d\n", value);
}
📌 C++ 스타일 (네임스페이스 활용)
#include <iostream>
namespace MyNamespace {
int value = 10;
void printValue() {
std::cout << value << std::endl;
}
}
int main() {
MyNamespace::printValue(); // 네임스페이스를 통해 접근
}
📌 정리:
- C는 전역 변수 충돌 문제가 발생할 가능성이 큼
- C++에서는 namespace를 사용하여 충돌을 방지할 수 있음
📌 정리
✅ C는 절차적 언어, C++는 객체지향 언어
✅ C++는 변수 선언, 메모리 관리, 참조자, 네임스페이스 등의 기능 추가
✅ C++는 스마트 포인터와 new/delete를 활용해 더 안전한 메모리 관리 가능
'SW > C++' 카테고리의 다른 글
6장. 복사 생성자와 임시 객체 (0) | 2025.02.26 |
---|---|
5장. 클래스 (0) | 2025.02.26 |
4장. 함수와 네임스페이스 (0) | 2025.02.26 |
3장. C++의 주요 기본 개념 (0) | 2025.02.11 |
1장. C만 배워본 내가 C++을 시작 (0) | 2025.02.11 |