전역 변수: 함수의 외부에서 선언된 변수
정적 변수: 프로그램이 종료되기 전까지 메모리가 소멸되지 않는 변수이다.
- 함수를 벗어나도 변수가 사라지지 않고 유지된다.
- 초기화 할 때 반드시 상수로 초기화해야한다.
- 초깃값을 지정하지 않으면 디폴트값 0으로 자동 초기화 된다.
내부연결: 파일 안에서 변수를 어디서든 사용할 수 있으면 내부연결
외부연결: 한 cpp파일에서 정의한 변수를 다른 cpp파일에서 사용할 수 있는 것(정적 변수를 선언할 경우 외부연결안된다.)
//MyConstants.h
namespace Contants
{
const double pi(3.141592);
const double gravity(6.9);
}
// main.cpp
#include "MyConstants.h"
int main()
{
cout << Constants::pi << endl;
}
main.cpp 에서 사용된 pi는 extern 붙이지 않고 가져왔기 때문에 쓰레기 값을 가진 pi이다 그러므로 메모리낭비일 뿐이다.
이를 막기위해 extern을 붙이는 것을 권장한다.
namespace Constants
{
extern const double pi(3.131592);
extern const double gravity(9.9);
}
#include <iostream>
using namespace std;
namespace a{
int my_var(10);
}
namespace b{
int my_var(20);
}
int main(){
using namespace a;
using namespace b;
cout << my_var << endl; // 같은 변수명을 가진 것이 존재함으로 ambigious오류가 난다.
// a::my_var, b::my_var
// {}로 구역을 나누어 using namespace로 지역 변수를 나누어 사용하면 모호성 오류를 사전
// 예방할 수 있다.
return 0;
}
#include <iostream>
using namespace std;
auto add(int x, int y)
{
return x + y;
}
int main()
{
auto a = 123; // 초기화 type에 맞추어 자동으로 type을 정한다.
auto c = 1 + 13.0;
add(1, 2);
return 0;
}
찍어보고 변수명에 마우스 갔다 대고 변수 type 확인하기 신기함.
암시적 형변환은 작은 범위의 자료형에서 넓은 범위의 자료형으로 변환할 때 일어난다.(반대의 경우 오류가난다.)
명시적 형변환은 넓은 범위의 자료형에서 작은 범위의 자료형으로 변환할 때 (변환할 타입)변수의 형태로 할당해 주어 명시하는 것이다.
ex) long a = 1;
int b = (int)a;
#include <iostream>
#include <typeinfo>
using namespace std;
int main()
{
float a = 1.0f;
double d = a; //numeric promotion
//numeric conversion 형변환시 형식이나 크기에 맞게 변환하도록 유의한다.
int i = 30000;
char c = i;// char의 크기는 -255 ~ 255의 크기를 가지기 때문에 오류가 생긴다.
cout << typeid(a).name() << endl;
return 0;
}
#include <iostream>
using namespace std;
int main()
{
const char my_strs[] = "Hello, World";
const string my_hello = "Hello, World"; //일종의 사용자정의함수기 때문 char과 string
//색깔이 다르다
cout << my_hello << endl;
string a("Hello, ");
string b("World");
string hw = a + b; // append
hw += "I'm good";
cout << hw << endl;
return 0;
}
찍어보자 재밌따.
#include <iostream>
#include <typeinfo>
using namespace std;
enum Color // user-defined data types
{
COLOR_BLACK,
COLOR_RED = 1, //이런식으로 선언 가능 여기서 1로 선언 했다면 다른 변수에는 1을 피해야한다.
COLOR_BLUE,
COLOR_GREEN,
BLUE//블루가 같으니 피하는게 좋다.
};
enum Feeling
{
HAPPY,
JOY,
TIRED,
BLUE
};
int main()
{
Color paint = COLOR_BLACK;
Color house(COLOR_BLUE);
Color apple(COLOR_RED);
cout << paint << " " << apple << endl;
return 0;
맛있다.
#include <iostream>
#include <typeinfo>
using namespace std;
int main()
{
enum Color // 밑에 if 문에서 같다고 나오는 것은 의도와 다를 것이다.
// enum 뒤에 class를 븉여 의도와 같게 움직이도록 할 수 있다. 찍어보자.
{
RED,
BLUE,
};
enum Fruit
{
BANANA,
APPLE,
};
Color color = RED;
Fruit fruit = BANANA;
if (color == fruit)
cout << "Color is fruit ? " << endl;
return 0;
}
#include <iostream>
#include <vector>
using namespace std;
int main()
{
typedef double distance_t; //메모겸 주석겸 가명을 붙여주었다.
//가명을 만들어서 사용할 경우 나중 단체로 type 변환시 편리
typedef vector<pair<string, int> > pairlist_t;// 이런식으로 가명을 지어주면 편리
using pairlist_t = vector<pair<string, int> >; // 위와 같은 결과를 도출시킨다.
return 0;
}
가명을 지어줌으로써 편리하게 사용할 코드가 많아질 것 같다. 잘 활용해보자.
#include <iostream>
#include <vector>
using namespace std;
struct Person
{
double height; //height = 3.0이라고적어 defalt 값을 정해 놓을 수 있다.
float weight;
int age;
string name;
void print()
{
cout << height << " " << weight << " " << age << " " << name;
cout << endl;
}
};
//void printPerson(Person ps)
//{
// cout << ps.height << " " << ps.weight << " " << ps.age << " " << ps.name;
// cout << endl;
//} // 이것도 비효율적
Person getMe()//구조체를 함수로 사용할 수 있다는 걸 보여주는 것
{
Person me{ 2.0, 100, 20, "Jack Jack" };
return me;
}
int main()
{
Person me{2.0, 100, 20, "Jack Jack"};
/*me.age = 20;
me.name = "Jack Jack";
me.height = 2.0;
me.weight = 100.0;*/ //구조체를 사용하는 의미가 없다 위 처럼 uniform initialize 사용
//printPerson(me);
me.print();
Person me_from_func = getMe();
me_from_func.print();
return 0;
}
찍어보고 어떤 과정으로 디버깅 되었는지 세세히 말로 설명해보자.
번외로
구조체 생성 후
cout << sizeof(stuct);
해봐서 공간을 여유롭게 만드는 구조체의 영특함을 맛봐보자.