[따배씨++]Chapter4. 변수범위와 더 다양한 변수형

Date:     Updated:

카테고리:

태그:

인프런에 있는 홍정모님의 홍정모의 따라하며 배우는 C++ 강의를 듣고 정리한 내용입니다.


🚆 지역변수의 범위와 지속기간 - scope vs duration

scope vs duration : 동적할당 가면 달라짐

int a = 3;
int a = 5; // error

int apple = 5;
{
  int apple = 10;
  cout << apple << endl; // 10
  cout << ::apple << endl; // 5
}
cout << apple << endl; // 5
  • 같은 범위 (scope{}) 내에서 동일한 이름의 변수는 사용 불가
  • 변수 이름이 같다면, 가장 가까운 범위의 변수가 우선 (name hiding)
  • 범위를 벗어나면 변수 데이터는 수명이 다해 사라짐


namespace work1
{
  int a = 5;
}

namespace work2
{
  int a = 3;
}

cout << work1::a << endl; // 5
cout << work2::a << endl; // 3
  • namespae를 통해 충돌 방지
  • nested namespace 가능


🚆 전역 변수, 정적 변수 & 내부 연결, 외부 연결

global vs static

global variable

int a = 5; // main 밖에서 선언

int main()
{
  ...
}
  • 다른 cpp파일에서도 값이 바꾸는 경우도 많아서 관리하기가 너무 빡셈
  • 지속기간이 없음. 프로그램 종료 때 사라짐
  • int g_a = 5; 이런 식으로 g_로 표기해주면 좋음
  • 사용하려면 const로, 되도록 안 쓰는 게 최고


static variable

void doSomething()
{
	static int a = 1;
	++a;
	cout << a << endl;
}

int main()
{
	doSomething(); // 2
	doSomething(); // 3
	doSomething(); // 4
	doSomething(); // 5
}
  • os로 부터 받은 메모리가 static(정적) ➡️ 메모리 공유
  • 초기화는 한 번만 시행되는데, 반드시 있어야 함
  • 해당 block (범위) 밖에서는 접근 불가
  • 함수가 몇 번 호출됐나 등 디버깅할 때 유용함
  • 범위가 벗어나도 메모리 유지
  • global varible 보다 static local variable 선호


Internal vs External Linkage

Internal Linkage

static int g_a = 5;
  • 다른 cpp파일에서 접근 불가능 (링커에 노출 X)


External Linkage

namespace Constatns // myConstans.h file
{
	extern const double pi = 3.141592;
	extern const double gravity = 9.8;

}

void doSomething(); // extern 생략

int main() 
{
	cout << Constatns::pi << endl;
	doSomething();
}

void doSomething()
{
	cout << 5 << endl;
}
  • 함수는 extern이 default값 (static 설정도 가능)
  • 전방 선언의 의미 : extern이니 어딘가에 몸통이 있다. 컴파일러 너가 알아서 찾아 써라
    • 만약 몸통이 없으면? 빌드는 되는데 컴파일에러남
  • 전역 변수 앞에 extern 붙이면 메모리 공유
    • extern 없어도 사용은 가능한데 값 복사해와서 사용 ➡️ extern 명시로 메모리 최적화 가능


🚆 using문과 모호성 (ambiguity)

namespace a
{
	int my_var = 123;
}

namespace b
{
	int my_var = 123;
}

int main()
{
	using namespace a;
	using namespace b;

	cout << my_var << endl; // error: my_var is ambiguous
}
  • using namespace a : 정의 안 되어 있으면 a 가서 찾아봐라.
  • 변수나 함수의 이름이 같은 경우가 생김
  • 특히 전역으로 사용하는 using이나 헤더 파일에서 using 넣어 버리면 에러 가능성이 커짐
  • using namespace는 risk 존재


정 쓰고싶으면

	{
		using namespace a;
		cout << my_var << endl; // error X
	}

	{
		using namespace b;
		cout << my_var << endl;
	}


🚆 Auto 키워드와 자료형 추론 - Type Inference

auto add(int x, int y)
{
	return x + y;
}

int main()
{
	auto a = 1 + 2.0; // a : double
}
  • 변수, 함수 리턴에 사용 가능
  • 함수 parameter에는 사용 불가


🚆 암시적 형변환과 명시적 형변환

Implicit Type Conversion

double a = 3.14;
int b = a; 

cout << b << endl; // 3
cout << 5u - 10 << endl; // 4294967291
  • 컴파일러가 알아서 타입 변환
  • 더 작은 타입으로 변환 시 데이터 손실
  • 주의) unsinged 가 우선순위 더 높음


Explicit Type Conversion

	int a = int(3.14);
	int a = static_cast<int>(3.14); // 형 변환 강조하기 좋음
  • 프로그래머가 직접 변환
  • 강조하고 싶은 경우 static_cast<> (기능은 같음)


🚆 문자열 소개 - std::String

	const string my_hello = "Hello, world";
	const char my_strs[] = "Hello, world";
  • #include <string>
  • 기본 자료형처럼 사용할 수 있게 구현됨
  • 추가적인 편리한 기능들도 있음
    • ex) str1 + str2, length(), …


🚆 Enumerated Types

복잡한 이름들 말고 인덱스로 들고 다니고 싶다..!

enum Color
{
	COLOR_BLACK,	// 0
	COLOR_RED,	// 1
	COLOR_BLUE,	// 2
	COLOR_GREEN,	// 3
};


int main()
{
	Color paint = COLOR_BLUE;
 	Color apple = Color(1); // apple = red

	cout << paint << endl; // 2 출력
}
  • 모든 데이터 타입 가능
  • 실제로는 정수형으로 움직임
  • 전역 변수처럼 작동하기 때문에 동일한 이름의 변수 명 사용 불가
  • Color1_enum의 black, Color2_enum의 black 이 같다고 인식 (내부적으로 0 == 0)


Enum Class!

enum class color1
{
	red,
};

enum class color2
{
	red,
};

int main()
{
	color1 red1 = color1::red;
	color2 red2 = color2::red;

	if (red1 != red2) // error : 비교 불가
		cout << "differ" << endl;
}
  • 동일한 이름의 변수 구별 & 사용 가능
  • 정수로 작동 X


🚆 기존 자료형에 가명 붙여주기 - typedef

double distance;
typedef double distance_t; // 컴파일러 입장에서 같음

distance_t home2work;


typedef vector<pair<string, int>> pairlist_t;
using pairlist_t = vector<pair<string, int>>;
  • 이해하기 쉬움 (메모겸 주소겸..)
  • 자료형이 복잡할 경우 유용함 (using쓰기도 함)


🚆 구조체 - struct

struct Person {
	// default initialize
	double height = 170.0;
	float weight = 100.0;
	int age = 25;
	string name = "Mr. Incredible";

	void print()
	{
		cout << height << "" << weight << ... << endl;
	}
};

int main()
{
	Person me{ 200.0, 100.0, 20, "Jack Jack" };
	cout << me.age << endl; // .(dot) operator로 접근
	
	Person my_friend(me); // static variable 있으면 조심해야 함
}
  • 여러가지 자료형들을 하나로 묶어서 관리할 수 있다.
  • c++는 구조체에 함수도 가능
  • nested struct 가능
  • struct 와 class의 차이는 default가 public이냐 private이냐 라고 함
  • struct끼리 assignment는 조심해서 해야 함


구조체 자료형 크기 - Padding

struct Employee    // 2 + (2) + 4 + 8 = 16 padding
{
	short id;       // 2 bytes
	int age;        // 4bytes
	double wage;    // 8 bytes
};


int main()
{
	cout << sizeof(Employee) << endl; // 16 bytes
}
  • 2 bytes 껴있으면 다루기가 좀 어렵나 봄..
  • 컴파일러가 4 bytes 처럼 들고다님
  • 변수들의 size, 순서가 최적화에 영향을 미침



맨 위로 이동하기

Cpp 카테고리 내 다른 글 보러가기

댓글 남기기