- int variables in memory
int num1 = 5;
int num2 = 129;
&num1 == ?
&num2 == ?
정수형 (int)는 4byte를 크기를 갖는다. num1의 주소가 10246이라 가정하면 10249 까지는 num1의 변수가 메모리에 저장된다.
'&' 주는 주소 연산자이며 해당 변수의 주소 값을 반환한다. 그렇기 때문에 &num1의 값은 10246이고 &num2의 값은 10272이다.
-double, float variables in memory
double a = 3.14;
float b = 1.1;
&a == ?
&b == ?
double 형과 float 형은 각각 8byte, 4byte의 크기를 갖는다. 아래 그림의 예를 가지고 a와 b의 주소 값을 구해보면 &a 값은 10246 값을 갖고, &b 값은 10272를 갖는다.
- char variable, C string in memory
char ch = 'A' ;
char str[10] = "Hello";
&ch == ?
str == ?
문자 열는 1byte의 크기를 갖는다. ch 문자열 변수는 크기가 1byte이며, &ch 주소 값은 10244를 갖는다. str 문자열 배열은 10byte의 크기를 갖는다. 배열의 주소 값을 알고 싶을 때는 '&' 주소 연산자 없이 배열의 이름만 입력하면 된다. str의 주소 값은 10266이다.
<Practice>
#include <stdio.h>
int main()
{
char ch1 = 'a';
char* pch1 = &ch1;
printf("value of ch1: %d\n", ch1);
printf("address of ch1: %p\n", &ch1);
printf("value of pch1: %p\n", pch1);
printf("address of pch1: %p\n", &pch1);
return 0;
}
value of ch1: 97
address of ch1: 1636819
value of pch1: 1636819
address of pch1: 1636804
Pointer : 포인터는 주소를 저장하는 변수이다.
- int* : 정수형 변수의 주소를 저장한다.
- double* , char* , float* ,...
- & operator
- 변수의 주소를 반환
- 연산의 주소
- 변수 -> 주소
- * operator
- 연산자(포인터)가 가리키는 메모리 공간(변수) 언급한다.
- 양방향 연산자
- 주소 -> 변수
int num = 5;
int* pnum = #
// store 20 to the varaiable
pointed by pnum
*pnum = 20;
<quiz1>
#include <stdio.h>
int main()
{
int i = 10;
double d = 3.14;
char c = 'a';
int* pi = &i;
double* pd = &d;
char* pc = &c;
(*pi)++;
(*pd)++;
(*pc)++;
printf("%d %f %c\n", i, d, c);
return 0;
}
11 4.140000 b
*pi, *pd, *pc는 각각 i, d, c의 주소들을 가리킨다. 그 상태에서 *pi, *pd, *pc의 값들을 1씩 증가시키면 각 포인터 변수들이 가리키는 i, d, c 변수의 값들이 1씩 증가된다.
An Array in Memory
#include <stdio.h>
int main()
{
int arr[3] = {5, 10, 20};
printf("arr: %p\n", arr);
printf("&arr[0]: %p\n", &arr[0]);
printf("&arr[1]: %p\n", &arr[1]);
printf("&arr[2]: %p\n", &arr[2]);
return 0;
}
arr: 0x7fffe174bd2c
&arr[0]: 0x7fffe174bd2c
&arr[1]: 0x7fffe174bd30
&arr[2]: 0x7fffe174bd34
해당 코드의 결과 값을 보면 첫 번째 printf에서 arr를 출력하면 해당 배열의 첫 주소 값이 나온다. arr에 있는 원소들의 주소 값들을 출력하면 &arr[0]은 arr 주소 값과 같다. 그 이후 주소 값들을 자세히 보면 4씩 증가하는 것을 발견할 수 있다. 왜냐하면 정수형(int)은 4byte 크기를 메모리에 할당하기 때문이다.
<arr == &arr>
int arr[3] = {5, 10, 20};
printf("arr: %p\n", arr);
printf("&arr: %p\n", &arr);
arr: 0x7fffe174bd2c
&arr: 0x7fffe174bd2c
Arrays와 Pointer의 유사함 / 차이점
int arr[] = {5, 10, 15};
int* ptr = arr;
printf("%d %d %d %d\n", arr[0], *arr, ptr[0], *ptr);
5 5 5 5
<sizeof 연산자의 결과에서 차이>
int arr[3] = {5, 10, 20};
int* ptr = arr;
int size1 = sizeof(arr); // size1 = 12
int size2 = sizeof(ptr); // size2 = 4 (in 32-bit program)
<quiz2 - arr[i] == *(arr+i)>
#include <stdio.h>
int main()
{
int arr[] = {5, 10, 15, 20};
int* ptr = arr;
printf("%d %d\n", *(arr+3), ptr[1]);
return 0;
}
20 10
Call-by-value
void swap_wrong(int n1, int n2)
{
int temp = n1;
n1 = n2;
n2 = temp;
}
int main()
{
int num1=10, num2=20;
swap_wrong(num1, num2);
return 0;
}
num==10, num2==20
- 함수가 호출될 때, 메모리 공간 안에서는 함수를 위한 별도의 임시 공간이 생성된다. (c++의 경우 stack frame) 함수가 종료되면 해당 공간은 사라진다.
- 스택 프레임(Stack Frame) : 함수 호출 시 할당되는 메모리 블록(지역변수의 선언으로 인해 할당되는 메모리 블록)
- call-by-value 값에 의한 호출 방식은 함수 호출 시 전달되는 변수의 값을 복사하여 함수의 인자로 전달한다.
- 복사된 인자는 함수 안에서 지역적으로 사용되는 local value의 특성을 가진다.
- 따라서 함수 안에서 인자의 값이 변경되어도, 외부의 변수의 값은 변경되지 않는다.
Call-by-reference
void swap(int* p1, int* p2)
{
int temp = *p1;
*p1 = *p2;
*p2 = temp;
}
int main()
{
int num1=10, num2=20;
swap(&num1, &num2);
return 0;
}
num==20, num2==10
- 함수가 호출될 때, 메모리 공간 안에서는 함수를 위한 별도의 임시 공간이 생성된다. (예: stack frame) 함수가 종료되면 해당 공간은 사라진다.
- call-by-reference 참조에 의한 호출 방식은 함수 호출 시 인자로 전달되는 변수의 레퍼런스를 전달한다. (해당 변수를 가리킨다.)
- 따라서 함수 안에서 주소의 변수 값이 변경되면, argument로 전달된 해당 주소의 변수 값도 함께 변경된다.
'Language > C++' 카테고리의 다른 글
[C++] Namespace - 컴도리돌이 (0) | 2020.10.17 |
---|---|
[C++] 동적할당(Dynamic memory allocation) - 컴도리돌이 (0) | 2020.10.17 |
[C++] introduction to C++ - 컴도리돌이 (0) | 2020.10.15 |
[C++] Pointer and Const -컴도리돌이 (0) | 2020.10.14 |
[C++] 구조체 정의 - 컴도리돌이 (0) | 2020.10.13 |