int main()
{
int n = 10;
int& r = n;
int* p = &n;
const int c = 10;
const int& cr = c;
decltype(n) d1; // int d1
decltype(r) d2; // int& d2 초기화 문제 error
decltype(p) d3; // int* d3
decltype(c) d4; // const int d4 초기화 문제 error
decltype(cr) d5;// const int& d5 초기화 문제 error
}
int x = 10;
int foo() { return x; }
int& goo() { return x; }
int main()
{
foo() = 20; // 10 = 20 error
goo() = 20; // x의별명 = 20 ok
}
괄호 안의 식을 함수라고 보고 그 결과에 따라 판단
int main()
{
int n = 10;
int* p = &n;
decltype(p) d1; // int* d1;
decltype(*p) d2; // int& d2; 초기값 문제로 error
decltype(n) d3; // int d3;
decltype(n+1) d4; // int d4;
decltype((n)) d5; // int& d5;
decltype(n=20) d6; // int& d6;
int x[3] = {1,2,3};
decltype(x[0]) d7; // int& d7;
auto a1 = x[0]; // int a1;
decltype(x) d8; // int d8[3]
auto a2 = x; // int a2[3] = x 에러이므로
// int* a2 = x;
decltype(n++) d9; // int
decltype(++n) d10; // int&
}
decltype(함수이름): 함수의 타입
decltype(함수호출식): 함수 실행의 결과 타입 (함수 반환 타입), 실제 함수가 호출되는 것은 아니고 함수 구현이 없어도 선언만 있으면 사용 가능 (Unevaluated Expression)
int x = 0;
int foo(int a, int b);// { return 0;}
int& goo(int a, int b) { return x;}
int main()
{
decltype(foo) d1; // int(int, int)
// int d1(int, int)
decltype(foo(1,2)) d2; // int
// decltype(goo(1,2)) d3; // int&
}
int main()
{
auto ret1 = goo(1,2); // int ret1 = goo(1, 2)
//decltype(goo(1,2)) ret2 = goo(1, 2);
// int& ret2 = goo(1, 2)
decltype(auto) ret2 = goo(1, 2);
ret2 = 1000;
std::cout << x << std::endl; // 1000
}
/*
template<typename T> T Add(T a, T b) // 서로 다른 두 타입을 받아오지 못하는 한계
{
return a + b;
}
*/
template<typename T1, typename T2>
// decltype(a+b) Add(T1 a, T2 b) // 1. 선언되지 않은 변수 사용하여 컴파일 에러
//auto Add(T1 a, T2 b) -> decltype(a+b) // 2. suffix return, 정확한 타입 반환
//auto Add(T1 a, T2 b) // 3. return문의 표현식을 보고 타입 추론, 참조 타입 반환 불가
decltype(auto) Add(T1 a, T2 b) // 4. 참조 타입 반환 가능 (C++14)
{
return a + b;
}
int main()
{
std::cout << Add(1, 2) << std::endl;
std::cout << Add(1, 2.3) << std::endl;
}
배열의 이름은 배열의 주소가 아님;
int main()
{
int n = 0;
double d = 0;
// n과 d의 주소를 담은 포인터 변수 p1, p2 만들기
int *p1 = &n;
double *p2 = &d;
}
int main()
{
int x[3] = {1,2,3};
// 배열 x의 주소를 담는 포인터 변수 p3 만들기
int (*p3)[3] = &x; // 배열의 주소
}
int main()
{
int n1 = 10;
int n2 = n1;
double d1 = 3.4;
double d2 = d1;
int x[3] = {1,2,3};
int y[3] = x; // 컴파일 에러
}
int main()
{
int x[3] = {1,2,3};
int *p = x; // 배열의 주소가 아닌 배열의 이름
}
p는 배열이 아닌 배열의 첫번째 요소를 가리킴
int main()
{
int x[3] = {1,2,3};
int (*pa)[3] = &x; // 배열의 주소
int *pn = x; // 배열의 이름 - 배열의 첫번째 요소의 주소
printf("%p\n", pa);
printf("%p\n", pn);
}
pa와 pn의 출력값이 같아 동일해보임
int main()
{
...
printf("%p\n", pa+1); // 12byte 증가 sizeof(int[3])
printf("%p\n", pn+1); // 4byte 증가 sizeof(int)
}
int main()
{
...
// * 연산
int n1 = *pn; // *(int주소) -> int
int *p2 = *pa; // *(배열주소) -> 배열 -> 첫번째 요소의 주소로 형변환
int n2 = **pa;
}
int x[2] = {1,2};
// 1차 배열의 주소
int (*p1)[2] = &x;
int y[3][2] = {{1,2},{3,4},{5,6}};
int (*p2)[3][2] = &y; // 2차원 배열의 주소
int (*p3)[2] = y; // 배열의 이름 -> 배열의 첫번째 요소의 주소
// 1차원 배열의 주소
int *p4 = *y; // *(1차원 배열의 주소) -> 1차원 배열 -> 첫번째 요소의 주소
Quiz. 물음표 채워보기
int z[2][2][2] = {1,2,3,4,5,6,7,8};
? p5 = &z;
? p6 = z;
? p7 *z;
예상
int z[2][2][2] = { {{1,2},{3,4}}, {{5,6},{7,8}} };
int (*p5)[2][2][2] = &z;
int (*p6)[2][2] = z;
int (*p7)[2] = *z;