벌써 마지막이네요!
계속 파이썬만 해서 c는 까먹기 직전이었는데 이렇게나마 복습할 수 있어서 너무너무 좋았습니다 😊
다음 스터디도 신청할게요 크크
아는 언니한테 톡이 왔는데 개강이 2주 남았다네요?
이것 뭐에요 ~?
저는 올클해서 19학점을 듣습니다...
아아 졸업할 수 있어서 좋은데 안 좋아
아 심란해 엽떡 시켜 먹을게요
며칠 전에 그냥 읽으려고 한빛아카데미 - 네트워크 해킹과 보안을 구매했는데
재밌고 완전 만족스럽고 그렇습니다 다들 츄라이츄라이 ~
책장 보는데 생각보다 한빛미디어 책을 많이 샀더라고요?
회고를 올리면서 다른 책들 리뷰도 한번 해볼까 합니다 많관부 ~
그리고 코난 전시회를 다녀왔는데요
제 최애는 괴도키드입니다 네
포인터란?
사용 범위를 벗어나도 데이터를 공유할 수 있게 도와주는 것
⭐ 변수는 함수 내부에서만 사용할 수 있었으나, 함수 외부에서도 같은 데이터를 공유하기 위해 포인터를 사용한다.
메모리란?
데이터를 넣고 꺼내 쓰는 공간
⭐ 프로그램이 사용하는 메모리의 위치를 주소 값으로 식별 가능함
이미지처럼 int형 변수 a가 메모리 100번부터 할당되었을 때 100부터 103까지 4바이트에 걸쳐 할당됨
변수 선언 이후에 4바이트를 a로 사용하는 것
a = 10;은 4바이트의 공간에 10을 저장했다는 의미
a + 20;은 그 4바이트의 공간에 저장된 값과 20을 더하는 연산이라고 보면 된다.
주소 연산자(&)
변수를 이름이 아닌 주소로는 어떻게 사용할 수 있을까?
주소는 변수가 할당된 메모리 공간의 시작 주소를 의미함
메모리 주소를 전달하는 것이므로 메모리 효율성이 있는 방법
또, 주소를 전달해도 여러 함수에서 동일한 위치를 참조할 수 있어서 쉬운 공유 가능
//변수의 메모리 주소 확인
#include <stdio.h>
int main() {
int a; // int(정수)형 변수 선언
double b; // double(실수)형 변수 선언
char c; // char(문자)형 변수 선언
printf("a의 주소: %p\n", (void*)&a);
printf("b의 주소: %p\n", (void*)&b);
printf("c의 주소: %p\n", (void*)&c);
return 0;
}
//결과
a의 주소: 0x7ffee28d6a34
b의 주소: 0x7ffee28d6a28
c의 주소: 0x7ffee28d6a27
⭐ 주소를 통해 메모리 배치를 알 수 있다.
포인터의 선언과 사용
#include <stdio.h>
int main() {
int a = 10; // int(정수)형 변수 선언
int *pa; // int(정수)형 포인터 선언
pa = &a; // a 주소 대입
*pa = 10; // 포인터로 변수 a에 10 대입
// a의 값과 주소 출력
printf("a의 값: %d\n", a);
printf("a의 주소: %p\n", &a);
// p가 가리키는 값과 p 자체의 주소
printf("p가 가리키는 값: %d\n", *p);
printf("p의 값: %p\n", p);
return 0;
}
여기에서 '*'는 포인터임을 표시하는 기호라는 것을 잊지 말아야 한다.
반드시 주소 위치에 있는 변수의 자료형을 적어야 한다.
a가 메모리의 100부터 103까지 할당되었다면 주소 값 100은 pa에 저장된다.
간접 참조 연산자
//간접 참조 연산자
// * == 간접 참조 연산자
// pa == 포인터
*pa
여러 가지 포인터 사용해 보기
// p.269 예제 9-3
#include <stdio.h>
int main() {
int a = 10, b = 15, total; // 변수 선언과 초기화
double avg; // 평균 저장할 변수
int *pa, *pb; // 포인터 동시 선언
int *pt = &total; // 포인터 선언과 초기화
double *pg = &avg; // double형 포인터 선언과 초기화
pa = &a; // 포인터 pa에 변수 a의 주소 대입
pb = &b; // 포인터 pb에 변수 b의 주소 대입
*pt = *pa + *pb; // a값과 b값 더해 total에 저장
*pg = *pt / 2.0; // total 값을 2로 나눈 값을 avg에 저장
printf("두 정수의 값: %d, %d\n", *pa,*pb); // a값과 b값 출력
printf("두 정수의 합: %d\n", *pt); // total 값 출력
printf("두 정수의 평균: %.1lf\n", *pg); // avg 값 출력
}
// 결과
두 정수의 값: 10, 15
두 정수의 합: 25
두 정수의 평균: 12.5
const를 사용한 포인터
const를 사용하면 가리키는 변수의 값을 바꿀 수 없다는 의미가 됨
// p.272 예제 9-4
#include <stdio.h>
int main() {
int a = 10, b = 20;
const int *pa = &a; // 포인터 pa는 변수 a를 가리킨다.
printf("변수 a 값: %d\n", *pa); // 포인터로 간접 참조해 a 출력
pa = &b; // 포인터가 변수 b를 가리키게 한다.
printf("변수 b 값: %d\n", *pa); // 포인터로 간접 참조해 b 출력
pa = &a; // 포인터가 다시 변수 a를 가리킨다.
a = 20; // a를 직접 참조해 값을 바꾼다.
printf("변수 a 값: %d\n", *pa); // 포인터로 간접 참조해 바뀐 값 출력
return 0;
}
// 결과
변수 a 값: 10
변수 b 값: 20
변수 a 값: 20
포인터 완전 이해하기
포인터
1. 주소 저장
2. 포인터끼리 대입 가능
3. 대입 연산 기준 엄격
주소와 포인터의 차이?
주소는 변수에 할당된 메모리 저장 공간의 시작 주소 값 자체
포인터는 그 값을 저장하는 다른 메모리 공간
변수의 주소는 변하지 않지만, 포인터는 가리키는 주소를 바꿀 수 있어 다른 변수를 참조하게 할 수 있다.
아래 사진과 같이 지정했더라도
이렇게 하나의 변수를 지정하도록 주소를 바꿀 수 있다.
주소와 포인터의 크기
포인터도 저장 공간이기 때문에 크기가 있다.
그 크기는 저장할 주소의 크기에 따라 결정되는데 크기가 클수록 더 넓은 범위의 메모리를 사용할 수 있다.
포인터의 크기는 컴파일러에 따라 다를 수 있지만, 모든 주소와 포인터는 가리키는 자료형과 상관없이!
그 크기가 같다.
포인터의 대입 규칙
1. 포인터는 가리키는 변수의 형태가 같을 때만 대입해야 한다.
2. 형 변환을 사용한 포인터의 대입은 가능하다.
'대외활동, 서포터즈 > 한빛아카데미 혼공학습단 12기' 카테고리의 다른 글
한빛미디어 책 추천 건 공유드립니다 (0) | 2024.08.19 |
---|---|
[혼공C] 컴퓨터학과의 혼공학습단 12기 회고록 (0) | 2024.08.18 |
[혼공C] 5주차_배열 (0) | 2024.08.11 |
[혼공C] 4주차_함수 (0) | 2024.08.11 |
[혼공C] 3주차_선택문, 반복문 (0) | 2024.07.21 |