[C 언어 데이터 구조 2] - 포인터 의 간단 한 복습
17177 단어 C 언어 데이터 구조 와 알고리즘
지침 은 C 언어의 중점 으로서 데이터 구조 에서 도 중요 한 역할 을 발휘 하여 지침 에 대한 이 해 는 우리 가 각종 데이터 구 조 를 실현 하 는 데 도움 이 된다.그래서 지침 내용 을 복습 할 필요 가 있다 고 생각 합 니 다.이번 복습 은 독자 가 지침 에 대해 대체적인 이 해 를 가지 고 주소 부 호 를 찾 고 간접 적 으로 부 호 를 찾 는 등 연산 자의 역할 을 알 고 지침 의 연산 등 을 알 고 있다 고 가정 하 는 것 이다.이번 복습 은 세부 적 인 내용 에 대한 복습 이 며 데이터 구조 에 대한 내용 복습 이다.
문자열 포인터
문자열 은 사실상 문자 배열 입 니 다. 문자열 의 지침, 즉 문자 배열 의 지침 을 말 합 니 다.
1.1 문자열 의 두 가지 표현
우 리 는 문자열 에 두 가지 표현 방식 이 있다 는 것 을 알 고 있 습 니 다. 우 리 는 문자 배열 로 표시 할 수도 있 고 문자 포인터 로 표시 할 수도 있 습 니 다. 다음 과 같 습 니 다.
char *sentence1 = "Do not go gentle into that good night!";
char sentence2[] = "Do not go gentle into that good night!";
위의 두 문장 을 우 리 는 모두 정상적으로 출력 할 수 있 고 아래 의 연산 자 [] 를 사용 할 수도 있 으 며 간접 주소 지정 부호 * 를 사용 할 수도 있다. 우 리 는 다음 과 같은 코드 를 볼 수 있다.
//
printf("%s
", sentence1);
printf("%s
", sentence2);
//
printf("%c", sentence1[0]);
printf("%c", sentence2[1]);
// ( )
printf("%c", *(sentence1+2));
printf("%c", *(sentence2+3));
출력 결 과 는 다음 과 같 습 니 다.
Do not go gentle into that good night!
Do not to gentle into that good night!
Do n
모든 코드 가 순조롭게 실행 되 었 음 을 알 수 있 습 니 다. 그러면 이 두 가지 방식 은 차이 가 있 습 니까?
1.2 문자 포인터 와 문자 배열 의 차이
실제로, 우 리 는 포인터 방식 으로 문자열 상수 로 정의 합 니 다. 수정 할 수 없습니다. 배열 로 정의 하 는 것 은 문자열 변수 입 니 다. 우 리 는 각각 sentence 1 과 sentence 2 로 다음 코드 를 테스트 합 니 다.
//
sentence1[2] = '#';
//
printf("sentence1 : %s
", sentence1);
이 중 sentence 1 이 실 행 될 때 이상 하 게 종료 되 었 으 며, sentence 2 의 실행 결 과 는 다음 과 같 습 니 다.
sentence2 : Do#not to gentle into that good night!
문자열 수정 이 성공 한 것 을 볼 수 있 습 니 다.
2. 동적 할당 메모리 의 함수
우리 가 데이터 구 조 를 실현 할 때 항상 동적 으로 메모 리 를 분배 해 야 한다. 동적 으로 메모 리 를 분배 하 는 방법 은 malloc. h 라 이브 러 리 에서 다음 과 같은 몇 가지 방법 을 살 펴 보 자.
방법 이름
함수 원형
방법 작용
malloc
void *malloc(unsigned long size);
시스템 에 size 크기 의 메모 리 를 신청 하고 유형 없 는 지침 을 되 돌려 줍 니 다.
calloc
void *calloc(unsigned int n , unsigned int size);
시스템 에 n * size 크기 의 메모 리 를 신청 하고 유형 없 는 지침 을 되 돌려 줍 니 다.
realloc
void* realloc(void* pointer, unsigned int new_size);
p 가 가리 키 는 메모 리 를 확장 하여 유형 없 는 지침 을 되 돌려 줍 니 다.
free
void free(void *p);
p 지향 메모리 사용
구체 적 으로 이 함수 들 을 말 하기 전에, 우 리 는 다시 창 고 를 복습 합 시다.
2.1 창고
우 리 는 먼저 창고 가 무엇 인지 보 자.
스 택: 시스템 에서 자동 으로 분배 되 고 속도 가 빠 릅 니 다.하지만 프로그래머 는 통제 할 수 없다.
더미: 프로그래머 가 배정 하 는 메모리 로 보통 속도 가 느 리 고 메모리 조각 이 생기 기 쉬 우 나 사용 하기에 가장 편리 합 니 다.
우리 가 평소에 코드 를 쓰 는 것 처럼 다음 과 같은 문구 입 니 다.
int a = 10;
char ch = 'a';
float f = 1.4;
위 에 있 는 것들 은 모두 스 택 에 신청 한 변수 입 니 다.위 에서 말 한 동적 분배 메모리 함수 분 배 는 더미 에 분 배 된 변수 입 니 다.
2.2 malloc 함수 와 free 함수
이 함 수 를 사용 할 때 부적 절 한 성형 변수 size 를 입력 합 니 다. 이 함 수 는 시스템 저장 소 에 size 크기 의 메모 리 를 신청 하고 이 메모리 의 첫 번 째 주소 의 무 유형 지침 을 되 돌려 줍 니 다.신청 이 실 패 했 을 때 (메모리 부족) NULL 로 돌아 갑 니 다. 다음 코드 를 보 겠 습 니 다.
int *p = malloc(sizeof(int)*5);
우 리 는 int 크기 의 메모리 5 개 를 할당 하여 유형 없 는 포인터 로 되 돌려 주 었 습 니 다. 많은 튜 토리 얼 에서 필요 한 유형 으로 강하 게 바 꾸 었 습 니 다. 실제로 필요 하지 않 습 니 다. (시험 이 라면 강 한 전환 이 필요 합 니 다)
더미 에서 신청 한 메모리 이기 때문에 수 동 으로 풀 어야 합 니 다.
free(p)
2.3, calloc 함수 와 realloc 함수
다음 코드 를 보 겠 습 니 다.
int *p = calloc(5, sizeof(int));
용법 상 malloc 와 다른 점 이 있어 서 우리 도 많은 설명 에 불과 하 다.
그 다음 에 우리 의 realloc 함수 입 니 다. 이것 은 용법 이 비교적 풍부 한 함수 입 니 다. 이 함 수 를 사용 할 때 우 리 는 미리 메모리 하 나 를 분배 해 야 합 니 다.
int *p = malloc(sizeof(int)*5);
그리고 우 리 는 이 원래 의 메모 리 를 확장 합 니 다.
p = realloc(p, sizeof(int)*10);
이 함 수 는 유형 이 없 는 지침 을 되 돌려 줍 니 다. p 후 연속 주소 가 충분 하면 원래 의 p 로 돌아 갑 니 다. 그렇지 않 으 면 새 주 소 를 할당 합 니 다.우 리 는 다음 과 같은 코드 를 본다.
#include
#include
int main(){
int *p = malloc(sizeof(int)*5);
// ,
printf("before realloc p = %p
", p);
// p sizeof(int)*10
p = realloc(p, sizeof(int)*10);
//
printf("after realloc 10 p = %p
", p);
// p sizeof(int)*1000
p = realloc(p, sizeof(int)*1000);
//
printf("after realloc 1000 p = %p
", p);
//
free(p);
return 0;
}
출력 결 과 는 다음 과 같 습 니 다.
before realloc p = 00AB1658
after realloc 10 p = 00AB1658
after realloc 1000 p = 00AB3E38
첫 번 째 확장 은 메모리 가 충분 하기 때문에 원래 주소 에서 확장 되 고 두 번 째 메모리 가 부족 하기 때문에 메모리 하 나 를 새로 신청 한 것 을 볼 수 있 습 니 다.
메모리 가 부족 하면 새 주 소 를 확장 하 는 과정 에서 원래 주소 의 내용 도 복 사 됩 니 다.
그 밖 에 realloc 함 수 는 축소 에 도 사용 할 수 있 습 니 다.
p = realloc(p, sizeof(int))
우 리 는 또한 realloc 로 메모 리 를 방출 할 수 있다.
realloc(p, 0);
p = NULL;
3. 포인터 초기 화
포인터 의 초기 화 방식 은 다양 합 니 다. 우 리 는 동적 으로 메모 리 를 할당 하 는 방식 으로 초기 화 할 수도 있 고 주소 부 호 를 찾 을 수도 있 으 며 직접 할당 하 는 방식 도 사용 할 수 있 습 니 다. 하나씩 알 아 보 겠 습 니 다.
3.1 주소 부적 사용
이것 은 우리 가 자주 사용 하 는 방식 입 니 다. 우 리 는 먼저 변 수 를 정의 하고 초기 화 한 다음 에 주소 부 호 를 사용 하여 이 변수의 주 소 를 포인터 변수 에 할당 합 니 다.사람들 은 다음 과 같은 코드 를 본다.
int a = 10;
int *p = &a;
우리 가 처음에 지침 을 배 웠 을 때 우 리 는 이런 방식 을 배 웠 다. 이 방법 도 비교적 자주 사용 하 는 것 이 므 로 더 이상 자세히 말 하지 않 겠 다.
3.2 직접 할당
주소 부 호 를 가 져 오 는 것 을 제외 하고 우 리 는 직접 값 을 부여 하 는 방식 을 사용 할 수 있 습 니 다. 즉, 우 리 는 주 소 를 알 고 이 주 소 를 포인터 변수 에 할당 할 수 있 습 니 다.
int *p = 1001;
이런 방식 은 일반적으로 사용 하지 않 는 다. 왜냐하면 우 리 는 보통 상황 에서 자신 이 특정한 주 소 를 지정 하지 않 고 컴퓨터 를 직접 분배 하면 되 기 때문이다.
3.3 포인터 로 값 부여
포인터 변 수 는 기본 형식 변수의 대부분 동작 이 있 습 니 다. 할당 작업 도 물론 있 습 니 다. 우 리 는 먼저 포인터 변 수 를 만 들 고 초기 화 한 다음 에 이 포인터 값 을 다른 포인터 변수 에 할당 합 니 다.
int x = 10;
int *p1 = &x;
int *p2 = p1;
이런 방식 은 우리 도 자주 사용 하지만 이런 방식 에 대해 우 리 는 이것 이 지침 의 * * = 연산 * 이 라 고 생각 합 니 다.
3.4 동적 초기 화
동적 초기 화 란 우리 가 위 에서 말 한 것 처럼 동적 으로 메모 리 를 분배 하 는 함수, 수 동 으로 메모 리 를 분배 하 는 것 이다.코드 는 다음 과 같 습 니 다:
int *p = malloc(sizeof(int));
이런 방식 의 특징 은 분 배 된 메모리 가 스스로 소각 되 지 않 고 프로그래머 가 수 동 으로 소각 해 야 한 다 는 것 이다.
여기 서 우 리 는 지침 의 지침 을 간단하게 한 번 복습 하 였 으 며, 더 많은 내용 은 독자 스스로 이전의 학습 에서 찾 아야 한다.