[임베디드 C] 포인터
주소의 개념
모든 변수들은 주소
가 존재합니다.
변수
: 특정 메모리영역에 써있는 값
&변수
: 특정 메모리영역의 위치(주소)
배열
: 배열 시작
메모리영역의 위치(주소) , index마다 4바이트씩
차이가 난다.
printf("%X",변수주소);
를 통해 변수의 주소를 출력할 수 있습니다.
int의 주소는 4바이트지만 주소를 나타낼때는 맨 앞부분 주소
만 사용
&a가 0x1000이면 &(a+1)은 0x1004이다.
Trace
중단점(Break Point) 좌측 바 클릭하거나F9
으로 하고,
F5
로 trace 모드 진입,
F10
으로 다음 브레이크 포인트로 이동
포인터
포인터 변수의 줄임말로 메모리 주소를 보관
하는 변수, 변수를 가리킨다
라고 생각하면 이해하기 편하다. 가리킨 영역의 값을 제어
할 수도 있다.
*포인터 변수 = &변수(변수의 주소)
#include <stdio.h>
int main() {
int x = 100;
int *p = &x;
int *g = &x;
printf("%d\n",x); // 100
*p = 5000;
printf("%d\n",*g); // 5000
printf("%d\n",x); // 5000
return 0;
}
포인터 & 배열
배열의 이름은 배열의 시작 메모리 영역의 주소
와 나타난다.
&arr[0] = arr
#include <stdio.h>
int main() {
int arr[5] = {1,5,3,2,6};
printf("%X\n", &arr[0]); // 61FF0C
printf("%X\n", arr); // 61FF0C
return 0;
}
포인터 변수에 배열의 첫 주소를 담을 수 있다.
*p = arr
== *p = &arr[0]
줄임 표현식
(p+0) -> p[0];
(p+1) -> p[1];
(p+2) -> p[2];
(p+3) -> p[3];
*(p+4) -> p[4];
#include <stdio.h>
int main() {
int arr[5] = {11,15,13,12,16};
int *p;
p = arr;
printf("%d %d", arr[2], p[2]); // 13 13
return 0;
}
arr는 배열 시작의 메모리영역의 주소를 의미하기 때문에, arr[2]와 p[2]는 똑같은 의미입니다.
포인터의 자동 변환
#include <stdio.h>
void kfc(int abc[5])
{
for(int i=0; i<8; i++)
{
printf("%d ", abc[i]); // 1 4 3 5 2 7 4 3
}
}
int main() {
int arr[] = {1,4,3,5,2,7,4,3};
kfc(arr);
return 0;
}
kfc라는 함수에는 정상적으로 arr의 주소를 받기 위해서는 int *abc
와 같이 작성을 해줘야합니다.
하지만, C언어 내부적으로 초기화되지 않은 1차원 배열
은 포인터로 자동 변환 됩니다.
int abc[5]
=> int *abc
2차원 배열 기본
2차원 배열은 가로 세로로 된 격자 형태가 아닌, 1차원 배열이 여러개가 모여있는 것이다.
배열의 이름은 배열 시작 메모리 영역의 주소
arr[0]
: 가장 위에 있는 1차원 배열의 이름
#include <stdio.h>
int main() {
int arr[2][3];
printf("%X\n",arr); // 61FF08
printf("%X\n", arr[0]); // 61FF08
}
arr[1]
: 두번째 배열이름
#include <stdio.h>
int main() {
int arr[2][3];
printf("%X\n",arr[1]); // 61FF14
printf("%X\n", &arr[1][0]); // 61FF14
}
2차원 배열 심화
#include <stdio.h>
int main() {
int arr[2][3] ={
{1,2,3},
{6,7,8}
};
printf("%d\n",arr[0][5]); // 8
}
-------------------
int *p = arr;
printf("%d\n",p[5]); // 8
0 x 3 + 5 = 5번째 칸
Const
const = 상수 의미로 값을 바꿀 수 없으며
, 포인터 변수 또한 마찬가지이다.
다른 곳을 가리킬 수 있지만, 가리킨 곳의 값을 변경할 순 없다.
#include <stdio.h>
int main() {
int x = 10;
int y = 123;
const int *p = &x;
p = &y; // 다른 주소 가리키기 가능
// p = 123 와 같이 값을 변경할 수는 없음
printf("%d", *p);
return 0;
}
문자열 초기화
초기화 방법 1
: char v[4] = "ABC"
초기화 방법 2
: const char *p = "ABC"
: 문자 길이
만큼의 배열을 지정해주지 않아도 된다.
#include <stdio.h>
int main() {
char *p = "ABC";
for(int i=0; i<3; i++)
{
printf("%c ", p[i]); // A B C
}
return 0;
}
변경 가능 vs 변경 불가능
방법 1
은 변경 가능 , 방법 2
는 변경 불가능
변경 가능
#include <stdio.h>
void abc(char *p)
{
p[1] = 'Z';
}
int main()
{
char arr[4] = "ABC";
abc(arr);
printf("%s",arr); // AZC
return 0;
}
변경 불가능
#include <stdio.h>
void abc(char *p)
{
p[1] = 'Z';
}
int main()
{
char *arr = "ABC";
abc(arr);
printf("%s",arr); // 에러 발생
return 0;
}
다중 문자열 다루기
char *vs[3] = {"ABCDE", "BTS", "KK"};
: 문자 길이
만큼의 배열을 지정해주지 않아도 된다.
출력
#include <stdio.h>
int main()
{
char *vs[3] = {"ABCDE", "BTS", "KK"};
printf("%s",vs[0]); // ABCDE
return 0;
}
읽기 전용 문자열
const char *ts[3][6] = {"ABCDE", "BTS", "KK"};
: 글자 변경 불가
정리
주소
- 주소를 담는 변수는 &
이다.
배열의 이름은 배열의 주소
를 의미한다. ex) arr = &arr[0]
ex) arr[3] = {1,2,3} 이라고 한다면 arr[0]는 값
을 나타내고 &arr[0]은 주소
를 나타낸다.
포인터
- 주소를 가리키는 변수 *
를 사용합니다.
포인터는 값
을 가리킬 수 없고 주소
를 가리킬 수 있습니다.
불가
*p
= arr[1];
가능
*p
= &arr[1];
Author And Source
이 문제에 관하여([임베디드 C] 포인터), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@dev-hoon/임베디드-C-포인터저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)