카메라 개발자 공부방(SW)

[9장] 변수와 주소 본문

Langauge/C

[9장] 변수와 주소

luckmart 2021. 9. 28. 22:39
반응형

자 다음은 변수와 주소에 대해 이야기해보겠습니다.

이 개념을 제대로 파악하지 못하면 다음 과정을 하는 것이 전혀 의미가 없을 정도로 굉장히 중요하니 집중하고 봅시다~!

 

모든 메모리에는 주소가 있습니다.

그리고 이 주소는 1byte마다 하나씩 할당되어있습니다.

#include <stdio.h>

int main()
{
    int n = 8;
    printf("%d\n", n);
    printf("%p\n", &n);
    return 0;
}

// 실행결과
// 8
// 00B9FAE0

위의 예제는 변수의 메모리 공간 주소를 출력하는 코드입니다. (%p 서식문자는 메모리의 주소를 출력할 때 사용됩니다.)

n이라는 메모리 공간을 아래와 같이 그려보면 다음과 아래와 같습니다.

n은 주소가 00B9FAE0로 시작되고 1byte 당 address가 각각 할당 되어있는 것을 주목해주세요.(정말 중요한 것은 메모리가 시작하는 주소입니다.)

 

메모리와 주소

&연산자는 변수 앞에 사용되면 그 변수 메모리의 시작 주소를 의미합니다.

위의 그림에서 &n은 n이란 메모리 공간의 시작 주소 값이고,
data type은 int* 입니다. (int data type의 address)라는 뜻입니다.

이 주소 연산에 대해서도 산술 연산(+, -)이 가능합니다.

#include <stdio.h>

int main()
{
    int n = 8;
    printf("%p\n", &n);
    printf("%p\n", &(n + 1));
    printf("%p\n", &(n + 2));
    printf("%p\n", &(n + 3));
    return 0;
}
// 실행결과
// 00B9FAE0
// 00B9FAE4
// 00B9FAE8
// 00B9FAEC

주소에 산술 연산을 하게 되면 메모리의 data type의 크기만큼 껑충껑충 건너뜁니다~! 
int형 data type의 address이니 산술 연산의 결과는 4byte(int 만큼)씩 건너뛰게 됩니다.

 

그렇다면 char* type을 기준으로 산술연산을 하게되면 어떻게 될까요?

#include <stdio.h>

int main()
{
    char c = 'a'
    printf("%p\n", &c);
    printf("%p\n", &c + 1);
    printf("%p\n", &c + 2);
    printf("%p\n", &c + 3);
    return 0;
}
// 실행결과
// 00B9FAE0
// 00B9FAE1
// 00B9FAE2
// 00B9FAE3

datya type 자체는 char형이기 때문에 산술 연산의 결과는 1 byte(char 만큼)씩 건너뛰게 됩니다.

어떤 메모리의 시작 주소를 안 다라는 건 1) 그 주소를 이용해서 메모리 자체(값)를 읽어 올 수 있고,
2) 그 메모리 내부의 값을 변경시킬 수 있습니다. ('2)'에 대해선 포인터 변수를 배울 때 이야기해보겠습니다.)

 

앞서 연산자 시간에 배운 [ ], * 연산자로 주소를 이용해서 메모리의 값을 읽어 올 수 있습니다.

[ ] 연산자 앞에는 항상 주소가 오고, 대괄호 사이엔 정수가 옵니다.

 

주소[(정수)] : 주소를 시작으로 data type × 정수만큼 이동한 번지의 메모리 공간 자체를 의미합니다.

*주소 : 주소가 참조하는 메모리 공간 자체를 의미합니다.

 

주소 연산자로 어떤 메모리에 접근한다고 하면, 그 메모리 공간에 새로운 이름이 붙었다고 생각하셔도 됩니다.

int n이란 변수 메모리가 연속적으로 있다고 가정한 그림

 

위의 예시처럼 연속된 메모리 공간이 있다고 가정합시다. &n[0]은 00F9FEB0 주소에서 4(data type)×0 만큼 이동해볼까요?

00F9FEB0 이겠죠? 00F9FEB0기 참조하는 메모리 공간의 값 자체는 4입니다. 00F9FEB0로 시작하는 메모리 공간 자체는 &n[0]이라는 이름으로 접근할 수 있습니다. &n[0]을 printf로 출력하게 되면 4라는 값을 확인할 수 있습니다.

 

&n[2]은 어떨까요? 00F9FEB0 주소에서 4(data type) × 2 만큼 이동한 메모리 주소는 00F9FEB8입니다.
그 메모리 공간 자체를 &n[2]로 접근할 수 있습니다.

 

이번엔 *&n을 확인해 봅시다.

&n의 값 자체는 00F9FEB0 이죠? 이 주소에 에스 트릭(*) 연산자를 붙이면 그 주소로 시작하는 data type 만큼의 메모리 공간 자체를 접근할 수 있습니다(*&n ). int* data address type이기 때문에 00F9FEB0 ~ 00F9FEB3의 메모리 공간을 int 형 data type으로 인식할 것입니다.

printf로 출력하게 되면 4라는 값을 확인할 수 있습니다.

 

*(&n + 2)을 한번 보시죠

00F9FEB0 + 8 만큼 이동하니 메모리 주소는 00F9FEB8 입니다. 그 메모리 공간 자체의 데이터 값에 접근하려면 *(&n + 2)로 접근을 할 수 있으니 printf로 출력하면 30이 출력됩니다.

 

이해가 되시나요? 종이와 펜을 이용해서 곰곰히 생각해보시면 좋습니다!

오늘은 변수와 주소, [ ], * 연산자에 대해서 공부해보았습니다.

'Langauge > C' 카테고리의 다른 글

[11장] 배열  (0) 2021.09.30
[10장] 포인터  (0) 2021.09.29
[8장] 사용자 함수  (0) 2021.09.27
[7장] 변수의 초기화와 대입  (0) 2021.09.26
[6장] 자료형(data type)  (0) 2021.09.25
Comments