반응형

정적(Static) 변수

  • 한 번만 초기화되며, 초기화 하지 않을 경우 컴파일러가 초기화한다.(int 일 경우 0 으로 초기화)
  • 프로그램이 종료될 때까지 유지된다.
  • 데이터 메모리 영역에서 관리한다.
  • 사용되는 예시) 클래스나 함수의 모든 인스턴스 간에 공유되는 변수를 선언하고 싶지만, 외부에서 보이지 않게 하고 싶을 때 주로 사용한다.
#include <iostream>

using namespace std;

int getNewID() {
  static int ID = 0;
  return ++ID;
}

int main() {
  cout << "ID: " << getNewID() << endl; // 1
  cout << "ID: " << getNewID() << endl; // 2
  cout << "ID: " << getNewID() << endl; // 3
  cout << "ID: " << getNewID() << endl; // 4
  cout << "ID: " << getNewID() << endl; // 5

  return 0;
}

상수(Const) 변수

  • 변수를 상수화 한다. 즉 변경할 수 없는 변수를 정의할 때 사용한다.
  • const 키워드의 위치에 따라 상수화할 대상이 달라지므로 유의해서 사용해야 한다.
  • 리터럴 값으로 대입했을 경우 컴파일 타임에 결정되고, std::rand()와 같은 값으로 대입했을 경우 런타임에 값이 결정된다.

상수화 예시

  • 포인터 변수가 가리키는 값을 상수화
  • 설명) ptr 포인터 변수가 가리키는 *ptr 이 const로 지정되었으므로 컴파일 오류 발생. a 는 일반 변수이므로 컴파일 문제가 없음.
#include <iostream>

using namespace std;

int main() {
	int a = 0;
	const int* ptr = &a;

	a = 1;       // 컴파일 통과
	*ptr = 2;    // 컴파일 오류 발생

	return 0;
}
  • 포인터 변수 자체를 상수화
  • 설명) ptr 포인터 변수 자체를 const로 지정했으므로 컴파일 오류 발생. a 는 일반 변수이므로 컴파일 문제가 없고, ptr 변수는 오직 a 변수의 주소만 가지게 된다.
#include <iostream>

using namespace std;

int main() {
	int a = 0;
	int b = 1;
	int* const ptr = &a;

	a = 1;       // 컴파일 통과
	*ptr = 2;    // 컴파일 통과
	ptr = &b;    // 컴파일 오류 발생

	cout << a << endl;

	return 0;
}
  • 함수 상수화 예시
  • 설명 : int getX(const Point* this); 와 같은 의미로 내부에서 멤버 변수를 변경할 수 없고, 같은 const 함수만 호출할 수 있다. 또한 this를 가지고 있지 않은 전역 함수는 const 함수로 만들 수 없다.
class Point {
    int x, y;
public:
    Point(int x, int y) : x(x), y(y) {}

    int getX() const {   // ✅ const 멤버 함수
        // x = 5;        // ❌ 컴파일 에러: const 함수 내에서 멤버 수정 불가
        return x;
    }
};
반응형

'Programming Language > C++' 카테고리의 다른 글

예외 처리  (0) 2025.10.30
레퍼런스 변수  (0) 2025.10.30
함수와 구조체  (0) 2025.10.30
포인터와 메모리  (0) 2025.10.29
C ++ 프로그래밍 기초  (0) 2025.10.29
반응형

함수

  • 특정 작업을 수행하는 코드 집합으로 정의한다.
  • 함수의 매개변수의 값은 포인터가 아닌 경우 복사가 이루어지기 때문에 성능을 위해 메모리가 큰 변수는 포인터를 매개변수로 사용하는 것을 권장한다.

구조체

  • 하나 이상의 변수를 묶어 새로운 자료형으로 정의한다.
  • 구조체 안의 멤버 변수에 접근하려면 멤버 선택 연산자(.)를 사용한다.
  • 메모리에 연속으로 할당된다.
#include <iostream>

using namespace std;

struct Person {
  string name;    // 이름
  int age;        // 나이
  float height;   // 키
  float weight;   // 몸무게
};

void check_age(Person* _adult, int _count) {
  for (int i = 0; i < _count; i++) {
    if (_adult[i].age >= 25) {
      cout << "name : " << _adult[i].name << endl;
      cout << "age : " << _adult[i].age << endl;
      cout << "height : " << _adult[i].height << endl;
      cout << "weight : " << _adult[i].weight << endl;
    }
  }
}

int main() {
  Person adult[3] = {
      {"Brain", 24, 180, 70},
      {"Jessica", 22, 165, 55},
      {"James", 30, 170, 65},
  };

  check_age(adult, 3);

  return 0;
}
반응형

'Programming Language > C++' 카테고리의 다른 글

레퍼런스 변수  (0) 2025.10.30
정적 변수와 상수 변수  (0) 2025.10.30
포인터와 메모리  (0) 2025.10.29
C ++ 프로그래밍 기초  (0) 2025.10.29
개념 정리  (0) 2025.10.29
반응형

포인터가 메모리 공간에 접근하는 방법

  • 프로그램이 동작할 때 연산 장치(CPU)는 주소(포인터 주소)를 통해 특정 메모리 공간에 접근한다.
  • 프로그램이 실행되는 동안 운영체제가 동적으로 메모리를 할당하거나 해제할 수 있기 때문에 메모리 주소가 실제 물리적 주소로 보기 어렵다. 따라서 메모리 주소는 실제 위치에 해당하는 가상 주소로 이해한다.

포인터

  • 메모리 주소를 저장하는 변수를 의미한다.
  • 포인터 변수의 크기는 데이터 형식과 상관없이 64bit 프로그램에서는 8byte, 32bit 프로그램에서는 4byte이다.
  • 형식 : 자료형 *포인터 변수 이름

포인터 변수가 가리키는 데이터에 접근

#include <iostream>

using namespace std;

int main() {
  char char_value = 'A';
  int int_value = 123;
  double double_value = 123.456;

  char* char_pointer_value = &char_value;
  int* int_pointer_value = &int_value;
  double* double_pointer_value = &double_value;

  // 일반 변수의 데이터 출력
  cout << "char_value: " << char_value << endl;
  cout << "int_value: " << int_value << endl;
  cout << "double_value: " << double_value << endl;
  cout << endl;

  // 역참조 연산자로 포인터 변수가 가리키는 데이터 출력
  cout << "*char_pointer_value: " << *char_pointer_value << endl;
  cout << "*int_pointer_value: " << *int_pointer_value << endl;
  cout << "*double_pointer_value: " << *double_pointer_value << endl;
  cout << endl;

  // 역참조 연산자로 원본 데이터 덮어쓰기
  *char_pointer_value = 'Z';
  *int_pointer_value = 321;
  *double_pointer_value = 654.321;

  // 일반 변수의 데이터 출력(업데이트 확인)
  cout << "char_value: " << char_value << endl;
  cout << "int_value: " << int_value << endl;
  cout << "double_value: " << double_value << endl;

  return 0;
}

포인터를 다룰 때 주의할 점

  • 포인터를 역참조하기 전에 포인터가 유효한 메모리를 가리키는지 확인해야 한다. 유효하지 않은 메모리를 가리키는 포인터를 역참조하려고 하면 세그멘테이션 실패런타임 오류가 발생할 수 있다.
  • 할당된 메모리의 범위를 벗아나는 포인터 연산은 피해야 한다.
  • 할당 해제된 메모리를 역참조하지 말아야 한다.

메모리

메모리 구역 주요 내용
Code(텍스트) 함수, 코드 명령어 저장 (read-only)
Data(정적 영역) 전역 변수, static 변수, const 전역 데이터
Stack(스택) 지역 변수, 함수 매개변수, 리턴 주소
Heap(힙) new, malloc 등으로 동적 할당된 데이터
분류 저장 위치  예시  비고
지역 변수 스택 int x = 5; 자동 소멸
전역/static 변수 정적 영역 static int a; 프로그램 종료 시 해제
new/malloc 할당 new int(5); 수동 해제 필요
STL 컨테이너 객체 스택 std::vector<int> v; 내부 데이터는 힙
함수 인자 / 리턴 스택 void f(int n) 호출마다 프레임 생성
문자열 리터럴 정적 영역 "Hello" 읽기 전용 데이터

스택(Stack) 과 힙(Heap) 비교

  • 스택 : 함수의 매개변수나 지역 변수처럼 대부분의 일반 변수는 스택 메모리 영역에 할당 된다. 따라서 스택 영역은 함수의 호출과 함께 할당되며 함수가 반환되면 자동으로 소멸된다. 스택 영역은 크기가 한정되어 있으며, 이 크기를 초과할 때는 운영체제가 해당 프로그램을 강제로 종료한다.
  • 힙 : 동적으로 할단된 변수는 힙 메모리 영역에 할당 되며, 힙은 스택보다 훨씬 큰 메모리 풀이다. 힙에 할당된 메모리는 명시적으로 해제하기 전에는 해당 프로그램이 종료될 때까지 계속 유지되어, 메모리 누수가 발생할 수 있다.
구분 스택(Stack)  힙(Heap)
할당 방식 컴파일러에 의해 자동 관리 프로그래머가 수동으로 관리 (new, delete)
생명주기 블록(scope)을 벗어나면 자동 소멸 명시적으로 해제 전까지 유지
접근 속도 빠름 (연속적 메모리) 느림 (포인터를 통한 간접 접근)
메모리 크기 제한적 (보통 수 MB 수준) 매우 큼 (운영체제 의존)
주요 용도 지역 변수, 함수 인자 객체, 동적 배열, 런타임 데이터
예외 발생 Stack overflow Memory leak, fragmentation

스택에 저장되는 데이터

분류  예시 코드  설명
기본형(Primitive) int x = 10; 지역 변수는 스택에 바로 저장
구조체/클래스(값 타입) MyStruct s; 구조체나 클래스가 지역 변수로 선언되면 스택에 저장
배열(정적 크기) int arr[3] = {1,2,3}; 크기가 고정된 배열은 스택에 저장
함수 매개변수 void foo(int a) 인자 a는 스택에 push됨
리턴 주소 / 임시 변수 함수 호출 시 자동 저장 함수 호출 스택 프레임에 포함됨

힙에 저장되는 데이터

예시 코드  설명
동적 객체 int* p = new int(5); new로 할당 시 힙 공간 사용
동적 배열 int* arr = new int[10]; 크기가 런타임에 결정될 때
STL 컨테이너 내부 데이터 std::vector<int> v;
v.push_back(1);
vector 객체 자체는 스택에 있지만, 저장 데이터는 힙에 할당됨
shared_ptr / unique_ptr auto ptr = std::make_shared<MyClass>(); 관리되는 대상 객체는 힙에 존재
문자열 std::string s = "Hello"; string 객체는 스택에 있지만, 내부 문자 버퍼는 힙에 존재

STL 컨테이너별 메모리 저장 구조

컨테이너 본체(객체) 저장 위치  내부 데이터 저장 위치  설명
std::array 스택 스택 고정 크기, 스택에 연속 저장
std::vector 스택 동적 크기, 데이터는 힙에 저장
std::string 스택 문자열 버퍼는 힙 (SSO 최적화 예외)
std::list
std::deque
스택 노드 단위로 힙 할당
std::map
std::unordered_map
스택 트리/해시 노드는 힙에 존재
std::shared_ptr
std::unique_ptr
스택 관리 객체는 힙, 포인터 자체는 스택
std::stack
std::queue
스택 내부 컨테이너(vector/list)가 힙 사용

 

반응형

'Programming Language > C++' 카테고리의 다른 글

정적 변수와 상수 변수  (0) 2025.10.30
함수와 구조체  (0) 2025.10.30
C ++ 프로그래밍 기초  (0) 2025.10.29
개념 정리  (0) 2025.10.29
[C++] 자료형(데이터 타입) 정리  (2) 2022.01.12
반응형

형식이 없음을 나타내는 void  활용

  • 함수의 반환값이 없음을 나타냄
void test()
{
	std::cout << "Test" << std::endl;
}
  • 함수의 매개변수가 없음을 나타냄
int test(void)
{
	std::cout << "Test" << std::endl;
	return 1;
}
  • 어떤 변수라도 가리킬 수 있는 제네릭 포인터를 만들때 사용
int int_value;
float float_value;

void *ptr_value;
ptr_value = &int_value;
ptr_value = &float_value;

N bit 의 정수 범위

  • signed : -2^(n-1) ~ 2^(n-1) -1
  • unsigned : 0 ~ 2^n -1

명시적 형변환 방법

  • static_cast<변환 형식>(변환 대상) : 논리적으로 변경할 수 있는 형 변환 모두 가능, 상속 관계에 있는 포인터끼리 변환도 지원(업케스팅 지원)
#include <iostream>
using namespace std;

class Base {};
class Derived : public Base {};

int main() {
    // 기본형 변환
    double d = 3.14;
    int i = static_cast<int>(d); // 실수 → 정수
    cout << i << endl; // 3

    // 상속 관계 변환 (업캐스트)
    Derived derived;
    Base* basePtr = static_cast<Base*>(&derived); // 안전

    // void* → 특정 타입
    void* vp = &i;
    int* ip = static_cast<int*>(vp);
    cout << *ip << endl; // 3
}
  • const_cast<변환 형식>(변환 대상) : 포인터 및 레퍼런스 형식에서만 사용 가능, const, volatile 제거할 때 사용
#include <iostream>
using namespace std;

void PrintValue(const int* ptr) {
    // const_cast로 const 제거
    int* modifiable = const_cast<int*>(ptr);
    *modifiable = 20; // 위험하지만 예시용
    cout << *modifiable << endl;
}

int main() {
    int x = 10;
    PrintValue(&x); // const 제거 가능
    cout << x << endl; // 20 출력
}
  • reinterpret_cast<변환 형식>(변환 대상) : 일반적인 명시적 형 변환과 동일함, const를 사용하는 변환 대상은 사용할 수 없음
#include <iostream>
using namespace std;

int main() {
    int x = 0x12345678;
    char* p = reinterpret_cast<char*>(&x);

    // 메모리의 첫 바이트 출력 (엔디안에 따라 다름)
    cout << hex << (int)(unsigned char)p[0] << endl;

    // 정수 주소를 포인터로 변환
    uintptr_t addr = reinterpret_cast<uintptr_t>(&x);
    int* samePtr = reinterpret_cast<int*>(addr);
    cout << *samePtr << endl; // 0x12345678
}
  • dynamic_cast<변환 형식>(변환 대상) : 클래스의 포인터 및 레퍼런스 변수 간의 형 변환 시 사용, 안전한 다운캐스팅(down-casting)을 위해 사용
#include <iostream>
using namespace std;

class Base {
public:
    virtual ~Base() = default; // RTTI용
};
class Derived : public Base {
public:
    void Speak() { cout << "I'm Derived" << endl; }
};

int main() {
    Base* base = new Derived();
    Derived* d1 = dynamic_cast<Derived*>(base); // 안전한 다운캐스트
    if (d1) d1->Speak();

    Base* another = new Base();
    Derived* d2 = dynamic_cast<Derived*>(another); // 실패 -> nullptr
    if (!d2) cout << "Cast failed" << endl;

    delete base;
    delete another;
}

사용자 정의 리터럴

  • 리터럴을 나타내는 접미사를 함수 이름으로 만든다.
  • 형식 : 반환 타임 operator"" 리터럴 접미사(매개변수)
#include <iostream>

using namespace std;

const long double km_per_mile = 1.609344L;

// _km 사용자 리터럴 정의
long double operator"" _km(long double val) {
  return val; // km 리터럴: 아무 작업 없이  그대로 반환
}

// _mi 사용자 리터럴 정의
long double operator"" _mi(long double val) {
  return val * km_per_mile; // mi 리터럴: mile을 km로 변환하여 반환
}

int main() {
  long double distance_1 = 1.0_km;    // km는 그대로 저장
  long double distance_2 = 1.0_mi;    // mile은 km 단위로 변환되어 저장

  cout << distance_1 + distance_2 << " km" << endl;   // km값으로 출력

  return 0;
}

2의 보수

  • 1의 보수에 1을 더하면 2의 보수를 구할 수 있다.
  • 2의 보수법은 양수의 모든 비트를 반전한 1의 보수에 1을 더해, 음수를 표현하는 방법으로 활용된다.
#include <iostream>

using namespace std;

int main() {
	unsigned int value = 10;

	int value_a = ~value; // 1의 보수

	cout << value_a << endl; // 결과 : - 11

	int value_b = value_a + 1; // 2의 보수

	cout << value_b << endl; // 결과 : -10

	return 0;
}

비트 연산

a b AND(&) OR(|) XOR(^)
0 0 0 0 0
0 1 0 1 1
1 0 0 1 1
1 1 1 1 0

 


논리 시프트 연산, 산술 시프트 연산

구분 논리 시프트 (Logical Shift) 산술 시프트 (Arithmetic Shift)
목적 단순히 비트를 이동 (unsigned 용도) 부호를 유지하면서 이동 (signed 용도)
빈 자리 채움 항상 0으로 채움 왼쪽 시프트: 0, 오른쪽 시프트: 부호 비트로 채움
적용 대상 unsigned 정수 signed 정수
부호 보존 여부 ❌ 부호 깨짐 ✅ 부호 유지
#include <iostream>
#include <bitset>
using namespace std;

int main() {
    unsigned char u = 0b10110010; // 178 (unsigned)
    signed char s = 0b10110010;   // -78 (signed, 2의 보수 표현)

    cout << "Before:" << endl;
    cout << "unsigned: " << bitset<8>(u) << endl;
    cout << "signed:   " << bitset<8>(s) << endl;

    // 오른쪽 시프트 2비트
    unsigned char u_shift = u >> 2;
    signed char s_shift = s >> 2;

    cout << "\nAfter >> 2:" << endl;
    cout << "Logical (unsigned): " << bitset<8>(u_shift) << endl;
    cout << "Arithmetic (signed): " << bitset<8>(s_shift) << endl;
}

/* 결과 값
Before:
unsigned: 10110010
signed:   10110010

After >> 2:
Logical (unsigned): 00101100
Arithmetic (signed): 11101100
*/
반응형

'Programming Language > C++' 카테고리의 다른 글

정적 변수와 상수 변수  (0) 2025.10.30
함수와 구조체  (0) 2025.10.30
포인터와 메모리  (0) 2025.10.29
개념 정리  (0) 2025.10.29
[C++] 자료형(데이터 타입) 정리  (2) 2022.01.12
반응형

C 와 C++ 의 차이

1. C 에 객체와 관련된 기능을 추가해 발전시킨 언어를 C++ 이라고 함.

 

2. C  는 메모리 크기, 위치 등을 개발자가 직접 관리해야 한다.

 

3. C++ 은 자동으로 메모리를 할당하거나 해제할 수 있는 new, delete 키워드를 지원합니다. 또한 레퍼런스라는 개념을 통해 포인터를 더 편하게 다룰 수 있게 되었으며, 가상 함수와 연산자 오버로딩을 지원하기 시작하면서 객체지향 언어의 특징인 다형성을 완전하게 지원하게 되었다. 

 

4. C++ 은 객체를 추상하는 방법으로 범용성을 구현한다.


C++ 프로그램 빌드 과정

1. C++ 로 작성한 코드는 #include, #define 와 같은 # 기호로 시작하는 지시문을 전처리하고 이렇게 준비된 소스코드를 오브젝트 코드로 컴파일합니다.그리고 소스에 포함한 각종 라이브러리와 오브젝트 코드를 연결하는 링크를 거쳐 최종 실행파일을 만드는 행위

 

2. 실행파일 생성

   - 전처리 : 소스 파일이 컴파일되기 전에 소스 코드를 변경하거나 확장하는 등의 작업을 의미(소스 코드 -> 소스코드)

   - 컴파일 : 컴퓨터의 프로세서는 사람이 작성한 코드를 당장 해석할 수 없으므로 프로세서가 이해할 수 있는 오브젝트 코드로 변경하는 과정.(소스 코드 -> 오브젝트 코드)

   - 링크 : 라이브러리나 여러 개의 오브젝트 파일을 하나의 실행 파일로 묶는 과정.(오브젝트 코드 -> 실행 파일)

반응형

'Programming Language > C++' 카테고리의 다른 글

정적 변수와 상수 변수  (0) 2025.10.30
함수와 구조체  (0) 2025.10.30
포인터와 메모리  (0) 2025.10.29
C ++ 프로그래밍 기초  (0) 2025.10.29
[C++] 자료형(데이터 타입) 정리  (2) 2022.01.12
반응형

◆ 네트워크 부하로 발생하는 현상

 1. 라우터의 과부하로 인해 패킷 유실이 발생

 2. TCP 재전송 타임아웃으로 TCP 연결 해제가 발생

 3. TCP 소켓에서 ECONNABORTED 오류가 발생

반응형

+ Recent posts