[따배씨++]Chapter6-1. 배열, 포인터, 참조
카테고리: Cpp
태그: Programming
인프런에 있는 홍정모님의 홍정모의 따라하며 배우는 C++ 강의를 듣고 정리한 내용입니다.
공부하는 식빵맘 님의 블로그를 참고했습니다.
🚆 Array
Array 선언
int arr1[5] = {}; // OK
const int a = 5;
int arr2[a] = {}; // OK
int b = 5;
int arr3[b] = {}; // error
int num = 0;
cin >> num;
int arr4[num] = {}; // error
const int num_students = 20;
int students_scores[num_students] = {0, 1};
cout << *students_scores << endl; // 0
cout << students_scores << endl; // &students_scores[0]
cout << &students_scores << endl; // &students_scores[0]
cout << &students_scores[0] << endl; // &students_scores[0]
cout << &students_scores[1] << endl; // &students_scores[0] + 4 bytes
- size는 컴파일 타임에 결정 → 정적 배열(static array)
- array의 이름은 “포인터” 역할 (첫 번째 원소의 주소)
Enum과 함께 쓰기
enum StudentName
{
JackJack, // 0
DASH, // 1
VIOLET, // 2
NUM_STUDENTS, // 3
};
int main()
{
int my_array[NUM_STUDENTS];
my_array[JackJack] = 1;
my_array[DASH] = 100;
return 0;
}
함수 파라미터로 넘어갈 때는 포인터
void doSomething(int students_scores[20])
{
cout << sizeof(students_scores) << endl; // 4
}
- 파라미터로 넘어갈 때는 그냥 포인터로 넘어감 (주소만 복사해서)
- sizeof() 찍어보면 주소 크기 4 찍힘 (포인터의 크기)
- size 사라짐!
- 배열로 표기하는 이유는 배열임을 강조하기 위해
정적 다차원 배열
const int num_rows = 3;
const int num_columns = 5;
int array[num_rows][num_columns] = { 0 }; // OK
int array[num_rows][num_columns] = // OK
{
{1, 2, 3, 4, 5},
{6, 7, 8, 9, 10},
{11, 12, 13, 14, 15}
};
int array[num_rows][num_columns] = // OK
{
{1, 2, }, // 1 2 0 0 0
{6, 7, 8, 9, 10},
{11, 12, 13, 14, 15}
};
int array[][num_columns] = // OK
{
{1, 2, }, // 1 2 0 0 0
{6, }, // 6 0 0 0 0
{11, 12, 13, 14, 15}
};
int array[][]; // error
int array[][2]; // error
- 주소 찍어보면 row 넘어가도 쭉 이어짐
- 내부적으로는 연속적인 1차원 배열인 형태
🚆 포인터
메모리 주소를 담는 변수
&
: address-of operator → 쟤 저기 살아요*
: de-reference operatpr → 주소에 직접 접근해서 확인
int x = 5;
int* ptr = &x;
*ptr = 7;
cout << x << endl; // 7
double d = 3.0;
double* ptr_d = &d;
cout << ( sizeof(ptr) == sizeof(ptr_d) )<< endl; // true
double* ptr_dd = &123.0 // error : &R-value 불가능 (reference는 가능!)
Null Pointer
#include <cstddef> // std::nullptr_t
int* ptr = nullptr;
if (ptr != nullptr) {};
nullptr_t nptr; // null pointer만 받을 수 있음
- nullptr 이용하면 포인터 관리하기 좋음
- nullptr_t 는 null 포인터만 받을 수 있는 변수
포인터와 정적 배열
int array[5] = { 0,1,2,3,4, };
int* ptr = array;
*ptr[1] = 100;
cout << array[1] << endl; // 100
cout << sizeof(array) << endl; // 20
cout << sizeof(ptr) << endl; // 4
- array의 이름은 “포인터” 역할 (첫 번째 원소의 주소)
- ptr을 통해 배열의 원소 값 변경 가능
- array이름과 포인터의 차이점은 sizeof
- Q. 배열이 아닌 포인터 ptr[1] → 쓰레기 값(컴파일은 됨)
포인터 연산
int array[] = { 9, 7, 5, 3, 1 };
int* ptr = array;
cout << uintptr_t(ptr) << endl;
cout << uintptr_t(ptr + 1) << endl; // uintptr_t(ptr) + 4
cout << uintptr_t(ptr + 2) << endl; // uintptr_t(ptr) + 8
- uintptr_t : 포인터 주소 정수로 깔끔하게 표기
- pointer + 1 → pointer + sizeof(data_type)
- array[i] = *(ptr + i)
🚆 C언어 스타일의 문자열 기호적 상수
char 포인터는 컴파일러가 특별 대우!
문자열 포인터
char* ptr = "Jack Jack"; // Error
const char* name = "Jack Jack"; // OK
const char* name1 = "Jack Jack";
const char* name2 = "Jack Jack";
cout << (uintptr_t)name1 << endl;
cout << (uintptr_t)name2 << endl; // name1과 주소 같음
- “Jack Jack” 은 R-value라 포인터에 담을 수 없음
- const pointer로는 선언 가능 (문자열만 가능)
- 내용 같으면 같은 주소에 담김 (컴파일러가 해줌)
문자열 cout
int int_arr[5] = { 1,2,3,4,5 };
char char_arr[] = "Hello World!";
const char* name = "Jack Jack";
cout << int_arr << endl; // 0000004B8156FB28
cout << char_arr << endl; // Hello World
cout << name << endl; // Jack Jack
- 문자열 포인터의 경우 주소가 아닌 \0 나올 때 까지 내용 출력 (특별 대우)
char c = 'Q';
cout << &c << endl; // Q儆儆儆儆儆儆儆儆儆儆儆儆儆儆儆儆儆?릖¼
- \0 나올 때 까지 내용 출력하니 이상한 값 나옴
print('a'); // char 혹은 int
print("a"); // 문자열. const char * 혹은 string 혹은 cahr [] 배열
' '
→ 문자" "
→ 문자열
댓글 남기기