인 스 턴 스 는 C+에서 포인터 와 참조 의 차 이 를 자세히 설명 합 니 다.
컴퓨터 에 데 이 터 를 저장 할 때 반드시 세 가지 기본 요 소 를 알 아야 한다.정 보 는 어디 에 저장 되 어 있 습 니까?저 장 된 값 은 얼마 입 니까?저 장 된 값 은 어떤 유형 입 니까?따라서 지침 은 정보 가 메모리 에 주 소 를 저장 하 는 특수 한 변수 로 지침 과 그 가 가리 키 는 변 수 는 동전 의 양면 과 같다.지침 은 C 언어 를 배 우 는 데 어려움 을 겪 었 고 C++에 인용 개념 이 하나 더 생 겼 다.초학 때 이 두 개념 을 헷 갈 리 기 쉬 우 니 다음은 몇 가지 예 를 통 해 양자 간 의 차 이 를 설명 한다.
1.지침 의 성명
위 에서 언급 한 바 와 같이 포인터 와 그 가 가리 키 는 변 수 는 동전 의 양면 과 같 기 때문에 주소 기호'&'를 통 해 변수의 주 소 를 찾 을 수 있 고 인용 기호'*'를 풀 면 주소 에 저 장 된 변수 값 을 찾 을 수 있다.
int data = 10; // data, 10, int
int* p_data = &data; // data , p_data
cout << " :" << int(p_data) << "\t :" << data << endl;
출력 결 과 는:주소:8191436 저장 한 값:10
주 소 는 기본적으로 16 진법 입 니 다.출력 할 때 int 형식 으로 변환 되 었 기 때문에 10 진법 으로 출력 합 니 다.출력 결 과 를 번역 하면 주소 인 코딩 이 8191436 인 위치 에 10 인 변수 data 를 저장 하고 더 나 아가 data 와*pdata 는 같은 것 을 나타 낸다.이해 에 도움 이 되도록 다음 그림 을 그 렸 습 니 다.
따라서 본질 적 으로 포인터 와 일반적인 변 수 는 큰 차이 가 없 으 며 포인터 변 수 는 인용 을 푸 는 방식 으로 포인터 에 해당 하 는 주소 에 저 장 된 수 치 를 찾 을 수 있 습 니 다.다음 과 같이 정의 한다 면:
int data = 10;
int* p_data = &data; // int p_data, int data ,
int** p_p_data = &p_data; // int* p_p_data, int* p_data
cout << "p_data:" << p_data << "\t :" << *p_data << endl;
cout << "p_p_data:" << p_p_data << "\t :" << *p_p_data << endl;
출력 결 과 는:p_data:00EFF96C 저장 한 값:10
p_p_data:00EFF960 저 장 된 값:00EFF96C
출력 결과 에서 보 듯 이 pp_data 에 저 장 된 값 은 pdata,그리고 pdata 에 저 장 된 값 은 바로 data 입 니 다.'사랑 해,사랑 해'와 같은 브리지 입 니 다.다음은 변수 와 포인터 간 의 관 계 를 중점적으로 분석 합 니 다.우 리 는 상기 예 에서 포인터 를 변수의 주소 로 초기 화 합 니 다.변 수 는 컴 파일 할 때 분 배 된 이름 이 있 는 메모리 입 니 다.포인 터 는 이름 을 통 해 직접 접근 할 수 있 는 메모리 에 만 개별 이름 을 제공 합 니 다.또한 위의 예 를 들 어 프로그래머 에 게 변수 10 의 이름 은 data 이다.컴퓨터 에 있어 변수 10 은 8191436 주소 가 존재 하 는 데이터 이다.프로그래머 와 컴퓨터 의 소통 을 실현 하 는 방식 은 바로 지침 이다.data 주소 지정 을 통 해 프로그래머 가 컴퓨터 의 저장 구 조 를 이해 할 수 있 도록 하 는 것 이다.마찬가지 로 주소 에 대한 인용 을 통 해 이 주소 에 저 장 된 데 이 터 를 쉽게 찾 을 수 있다.위 와 같은 상황 에서 포인터 의 출현 은 다소 불필요 해 보이 지만 포인터 의 진정한 용 도 는 실행 단계 에서 이름 이 없 는 메모 리 를 저장 값 으로 분배 하 는 것 이다.이런 상황 에서 포인터 로 만 메모리 에 접근 할 수 있다.
마지막 으로 포인터 성명 에 대한 조언:포인터 변 수 를 설명 할 때 정확 한 주 소 를 지정 해 야 합 니 다.그렇지 않 으 면 성명 의 포인터 변 수 는 어디 를 가리 키 는 지 모 르 기 때문에 시스템 붕 괴 를 초래 하기 쉽 습 니 다.
2、new 를 사용 하여 메모리 할당
메모리 4 구역 의 코드 구역,전역 구역,창고 구역 과 더미 구역 에서 언급 한 적 이 있 습 니 다.new 는 더미 구역 에 메모리 공간 을 만 듭 니 다.반환 값 은 이 메모리 공간의 주소 입 니 다.따라서 프로그래머 의 책임 은 이 주 소 를 포인터 에 부여 하 는 것 입 니 다.다음은 예시 입 니 다.
int* p_data = new int; // ,
*p_data = 10; // 10
cout << "p_data:\t" << p_data << "\t *p_data: " << *p_data << endl;
비 교 를 통 해 new 뒤에 데이터 형식 int 를 지정 하 였 습 니 다.마찬가지 로 pdata 도 int 를 가리 키 는 지침 으로 밝 혀 졌 다.이 는 컴퓨터 의 메모리 가 바이트 단위 로 되 어 있 기 때문에 서로 다른 유형의 변 수 는 서로 다른 바이트 를 차지 하기 때문에 new 를 사용 할 때 컴 파일 러 에 몇 바이트 의 저장 공간 을 분배 하 는 지 알려 야 하고 받 은 지침 도 성명 의 유형 과 일치 해 야 하기 때문이다.출력 결 과 는:p_data: 00D0D9A0 *p_data: 10
대형 데 이 터 를 처리 할 때,예 를 들 어 배열 을 처리 할 때 일반적으로 사용 하 는 방법 은 하나의 배열 형식의 데 이 터 를 정의 하고 정의 할 때 충분 한 공간 을 분배 하 는 것 이다.그러나 이 방법 은 너무 딱딱 하지만 new 를 사용 할 때 실행 단계 에 배열 이 필요 하 다 면 만 듭 니 다.필요 하지 않 으 면 만 들 지 않 습 니 다.가장 중요 한 것 은 프로그램 이 실 행 될 때 배열 의 길 이 를 선택 하 는 것 입 니 다.동적 배열 을 만 들 기 위해 new 를 사용 하 는 방법 을 살 펴 보 겠 습 니 다.C++에서 배열 이름 은 배열 주소,즉 배열 의 첫 번 째 요소 의 주소 로 해 석 됩 니 다.다음은 실례 입 니 다.
int Arr[10]; // 10 int
cout << "Arr:" << Arr << "\t&Arr[0]:" << &Arr[0] <<endl;
출력 결 과 는:Arr:008FFAB4 &Arr[0]:008FFAB4
이러한 성명 방식 은 처음부터 고정된 배열 의 길 이 를 설명 할 수 있 습 니 다.C++에서 동적 배열 을 만 들 때 배열 의 요소 유형 과 요소 수 를 new 에 게 만 알려 주면 됩 니 다.new 의 반환 값 은 같은 배열 의 첫 번 째 주소 입 니 다.
int ele_num = 10; //
int* p_arr = new int [ele_num]; //
new 를 통 해 쌓 인 공간 을 열 고 프로그래머 가 관리 하여 방출 합 니 다.따라서 new 메모리 가 사용 되 지 않 으 면 delete 를 통 해 변 수 를 만 들 고 delete[]를 사용 하여 열 린 배열 공간 을 방출 해 야 합 니 다.코드 는 다음 과 같 습 니 다:
int* p_data = new int;
*p_data = 10;
cout << "p_data: " << p_data << "\t*p_data:" << *p_data << endl;
int ele_num = 10;
int* p_arr = new int [ele_num];
for(int i = 0; i<9; i++)
*(p_arr+i) = i+2;
cout << "p_arr:" << p_arr << "\t\t*(p_array):";
for(int i = 0; i<9; i++)
cout << *(p_arr + i) << " ";
cout << endl;
delete p_data;
delete [] p_arr;
cout << "
****** delete ......*******" << endl;
cout << "p_data: " << p_data << "\t*p_data:" << *p_data << endl;
cout << "p_arr:" << p_arr << "\t\t*(p_array):";
for(int i = 0; i<9; i++)
cout << *(p_arr + i) << " ";
cout << endl;
출력 결 과 는 다음 과 같 습 니 다.p_data: 0082B1C8 *p_data:10
p_arr:0082BB58 *(p_array):2 3 4 5 6 7 8 9 10
*****delete 메모리 사용 후...*********
p_data: 0082B1C8 *p_data:-572662307
p_arr:0082BB58 *(p_array):-572662307 -572662307 -572662307 -572662307 -572662307 -572662307 -572662307 -572662307 -572662307
3.malloc 와 new 의 차이
C 언어 를 배 운 친구 들 은 모두 알 고 있 습 니 다.C 언어 에서 malloc 함 수 를 통 해 메모리 공간 을 열 었 습 니 다.malloc 의 함수 원형 은 다음 과 같 습 니 다.
void* malloc(unsigned int numbytes);
함수 원형 의 매개 변 수 를 통 해 알 수 있 듯 이 malloc 함 수 는 바이트 수 를 매개 변수 로 하여 고정 바이트 의 메모리 공간 을 엽 니 다.이것 은 new 와 첫 번 째 차이 가 있 습 니 다.new 는 바이트 수 를 스스로 계산 할 필요 가 없습니다.메모리 에 저 장 된 데이터 형식 과 메타 수 만 지정 하면 됩 니 다.함수 원형 의 반환 유형 을 통 해 알 수 있 듯 이 malloc 함 수 는 void*형식 으로 되 돌아 갑 니 다.사용 할 때 포인터 형식 을 지정 해 야 합 니 다.예 를 들 면:
int* p_malloc = nullptr; // int
p_malloc = (int*) malloc(10); // malloc int*
new 는 사용 할 때 필요 하지 않 습 니 다.요약 하면 malloc 는 사용 할 때 메모리 의 데이터 형식 과 메모리 길이 에 따라 처 에 필요 한 바이트 수 를 계산 한 다음 에 void*형식 으로 돌아 가 대응 하 는 형식의 지침 을 사용 하여 수신 해 야 합 니 다.new 는 사용 할 때 메모리 의 길이 와 메모리 의 데이터 형식 만 지정 하면 컴 파일 러 는 필요 한 바이트 수 를 자동 으로 계산 합 니 다.4.인용 한 성명 과 본질
C++에 정 의 된 변 수 를 참조 하 는 별명 이 추가 되 었 습 니 다.인용 의 가장 주요 한 용 도 는 함수 형 삼 이다.이렇게 하면 함 수 는 데이터 복사 본 이 아니 라 원시 데 이 터 를 사용 할 수 있다.이렇게 들 으 면 지침 과 다 를 것 이 없 는 것 같다.우 리 는 인용 한 성명 부터 말 하 자.
int data = 10;
int& p_data = data; // p_data
cout << "data:" << data << "\tp_data:" << p_data << endl; //p_data data
출력 결 과 는:data:10 p_data:10
출력 결 과 를 보면 pdata 와 data 는 하나의 변수의 두 가지 다른 명칭 일 뿐이다.인용 은 성명 할 때 초기 값 을 지정 해 야 하 며 포인터 처럼 먼저 설명 하고 값 을 부여 할 수 없습니다.다음은 함수 로 서 의 매개 변 수 를 인용 하여 인용 과 지침 의 차 이 를 설명 합 니 다.
template <typename T> //
void swap(T a, T b){
int temp;
temp = a;
a = b;
b = temp;
}
int main(void){
int a = 10, b = 20;
swap_value<int>(a,b); //
cout << "a:" << a << "\t\tb:" << b << endl;
swap_value<int&>(a,b); //
cout << "
a:" << a << "\t\tb:" << b << endl;
}
상기 코드 에서 볼 수 있 듯 이 값 전달 과 인용 전달 의 형 삼 은 모두 같 습 니 다.다른 것 은 인용 전달 일 때 실제 인삼 은 인용 으로 설명 되 고 인용 하 는 용법 은 사용 값 과 똑 같 습 니 다.출력 결 과 는 다음 과 같 습 니 다.a:10 b:20
a:20 b:10
놀랍게도 인용 전달 이 원시 데이터 의 값 을 바 꾸 었 다 는 것 은 지침 의 용법 과 일치 하지만 지침 은 swap 함 수 를 쓸 때 이렇게 써 야 한다.
void swap(int* a, int* b){
int temp;
temp = *a;
*a = *b;
*b = temp;
}
swap(&a, &b); //
종합 적 으로 보면 인용 은 변수의 또 다른 이름 으로 그 용법 은 변수 와 똑 같 지만 형 삼 으로 전 달 될 때 원시 데이터 의 값 을 바 꿀 수 있다.이러한 용법 상의 차 이 를 제외 하고 인용 의 본질은 바로 하나의 지침 상수 로 지침 이 가리 키 는 위 치 는 변 할 수 없 지만 지침 이 위 치 를 가리 키 는 값 은 변 할 수 있다 는 것 을 의미한다.즉:
// ,
int& p_a = a;
int* const p_a=&a;
조금 만 더 작은 지식 을 보충 하면 const 수식 부 에 관 한 문제 에 대해 어떤 초보 친구 들 은 const 가 무엇 을 가 변 적 이 고 무엇 을 가 변 적 이지 않 은 것 인지 알 지 못 하기 쉽다.구체 적 인 실례 는 다음 과 같다.
int data = 10, data2 = 20;
const int* p_data = &data; // int, p_data , p_data
p_data = &data2;
int* const p_data2 = &data; // int*, p_data , p_data
*p_data2 = data2;
인용 은 두 번 째 용법 이다.총결산
C++에서 포인터 와 인용의 차이 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 관련 C++포인터 와 인용 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 부탁드립니다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
hdu 1717 소수 화 점수 2 (수학)소수 화 점수 2 레이 는 수학 시간 에 선생님 의 말씀 을 듣 고 모든 소수 가 점수 로 표시 되 는 형식 이 라 고 말 했다. 그 는 녹 기 시 작 했 고 곧 완성 되 었 다. 그러나 그 는 또 하나의 문 제 를...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.