C++에서 전송 값,전송 주소 와 전송 인용 은 어떤 차이 가 있 습 니까?

인용 정의
전송 값 과 전송 주 소 는 모두 가 손금 보 듯 잘 알 고 있 을 것 이 라 고 믿 습 니 다.여기 서 먼저 인용 이 무엇 인지 소개 해 주 시 겠 습 니까?
인용 은 변 수 를 새로 정의 하 는 것 이 아니 라 존재 하 는 변수 에 별명 을 붙 였 습 니 다.컴 파일 러 는 인용 변 수 를 위해 메모리 공간 을 열 지 않 습 니 다.인 용 된 변수 와 같은 메모리 공간 을 사용 합 니 다.
솔직히 말 하면 인용 은 변수 에 별명 을 붙 이 는 것 이다.예 를 들 어 한 사람 이 유명,학명,필명 이 있 는데 사실은 모두 한 사람 일 뿐이다.
예:임 충,강호 에 서 는'표범 머리'라 고 부른다.
형식&인용 변수 이름(대상 이름)=인용 실체;

void TestRef()
{
int a = 10;
int& ra = a;  //<====      
printf("%p
", &a); printf("%p
", &ra); }

a 와 라 의 주소 가 같 음 을 알 수 있 고 인용 이 변수 자체 임 을 증명 할 수 있 습 니 다.
메모:인용 형식 은 인용 실체 와 같은 유형 이 어야 합 니 다.
대상 이 int 로 정의 되 었 으 면 인용 은 int&
인용 특성
1.인용 은 정의 할 때 초기 화 되 어야 합 니 다.

#include<iostream>
using namespace std;

void TestRef()
{
	int a = 10;
	int& ra;  //           
	int& ra = a;
	int& rra = a;
	printf("%p %p %p
", &a, &ra, &rra); } int main() { TestRef(); return 0; }

int ra&; // 초기 값 을 부여 하지 않 으 면 잘못 보고 할 수 있다.
2.하나의 변 수 는 여러 개의 인용 을 할 수 있 고 한 사람 은 여러 개의 별명 을 가 질 수 있다.

#include<iostream>
using namespace std;

void TestRef()
{
	int a = 10;
	int& ra = a;
	int& rra = a;
	printf("%p
%p
%p
", &a, &ra, &rra); } int main() { TestRef(); return 0; }

3.인용 은 한 실 체 를 인용 하면 다른 실 체 를 인용 할 수 없다.라 는 a 의 인용 후 다른 대상 을 인용 할 수 없다 는 뜻 이다.
인용 과 전달 값 의 차이
1.전송 값,전송 참조 되 돌아 오 는 비교
전송 값 반환:

#include<iostream>
using namespace std;

int Add(int a, int b)
{
	int c = a + b;
	return c;
}

int main()
{
	int ret=Add(1,2);
	cout << "ret:" << ret << endl;
	return 0;
}

메모:돌아 갈 때 c 는 자신의 값 을 임시 변수 에 복사 합 니 다.ret 는 c 의 복사 본 을 받 습 니 다.c 는 Add 함수 호출 이 끝 난 후에 스 택 프레임 이 소각 되면 서 소각 합 니 다.
c 의 복사 변 수 는 일반적으로 c 가 있 는 함수 에서 열 립 니 다.이 예 는 main 함수 에서 열 립 니 다.반환 변수 가 시간 이 많 을 때 업 계 는 레지스터 에 반환 변 수 를 저장 하 는 복사 공간 을 열 수 있 습 니 다.
인용 반환:

#include<iostream>
using namespace std;

int& Add(int a, int b)
{
	int c = a + b;
	return c;
}

int main()
{
	int& ret=Add(1,2);
	cout << "ret:" << ret << endl;
	return 0;
}
여러분,결과 가 뭘 까요?
3 인가요?

결 과 는 랜 덤 입 니 다.왜 일 까요?
c 의 인용,즉 c 자 체 를 되 돌려 주기 때문에 c 변 수 는 스 택 프레임 에 저 장 됩 니 다.함수 가 끝나 면서 스 택 프레임 이 소각 되 고 c 도 소각 되면 서 공간 이 방출 되 었 습 니 다.이때 불법 인용 을 초래 하고 값 은 랜 덤 값 입 니 다.
그럼 어 떡 하지?
c 를 스 택 프레임 에 넣 지 않 으 면 됩 니 다.c 를 정적 구역 에 두 면 됩 니 다.

#include<iostream>
using namespace std;

int& Add(int a, int b)
{
	static int c = a + b;
	return c;
}

int main()
{
	int& ret=Add(1,2);
	cout << "ret:" << ret << endl;
	return 0;
}


재 미 있 는 문제 하나 더 주세요.다음 코드 의 결 과 는 무엇 입 니까?

#include<iostream>
using namespace std;

int& Add(int a,int b)
{
	int c = a + b;
	return c;
}

int main()
{
	int& ret = Add(1, 2);
	Add(5, 7);
	cout << ret << endl;
	return 0;
}
많은 분 들 이 3 인 줄 알 겠 죠.

결 과 는 12 였 지만 Add(5,7)를 출력 하지 않 았 습 니 다.왜 12 일 까요?

Add(1,2)를 호출 한 후에 결 과 를 ret 로 되 돌려 줍 니 다.ret 는 이때 3 입 니 다.스 택 프레임 을 소각 하고 공간 을 방출 한 다음 에 Add(5,7)를 호출 하여 스 택 프레임 을 다시 열 었 습 니 다.이때 열 린 스 택 프레임 과 지난번 에 소각 한 곳 은 한 곳 입 니 다.ret 는 또한 이전 c 의 위 치 를 가리 키 고 있 습 니 다.이때 c=5+7;

#include<iostream>
using namespace std;

int& Add(int a,int b)
{
	int c = a + b;
	return c;
}

int main()
{
	int& ret = Add(1, 2);
	Add(5, 7);
	printf("    
"); cout << ret << endl; return 0; }
이 때 출력 은 랜 덤 값 입 니 다.printf 함 수 를 호출 하여 방출 된 공간 을 차지 하기 때 문 입 니 다.ret 는 원래 c 가 있 는 공간 을 가리 키 지만 값 은 랜 덤 값 입 니 다.

2.전송 값,전송 인용 효율 비교
값 을 매개 변수 나 반환 값 유형 으로 하고 전 삼 과 반환 기간 에 함 수 는 실제 인삼 을 직접 전달 하거나 변수 자 체 를 직접 되 돌려 주지 않 고 실제 인삼 을 전달 하거나 변 수 를 되 돌려 주 는 임시 복사 이기 때문에 값 을 매개 변수 나 반환 값 유형 으로 사용 하면 효율 이 매우 낮다.특히 매개 변수 나 반환 값 유형 이 매우 클 때 효율 이 더욱 낮다.

#include<iostream>
#include<time.h>
using namespace std;

struct A{ int a[10000]; };

void TestFunc1(A a){}

void TestFunc2(A& a){}

void TestRefAndValue()
{
	A aa;
	//         
	size_t begin1 = clock();
	for (size_t i = 0; i < 10000; ++i)
		TestFunc1(aa);
	size_t end1 = clock();

	//          
	size_t begin2 = clock();
	for (size_t i = 0; i < 10000; ++i)
		TestFunc2(aa);
	size_t end2 = clock();

	//                 
	cout << "TestFunc1(A)-time:" << end1 - begin1 << endl;
	cout << "TestFunc2(A&)-time:" << end2 - begin2 << endl;
}

int main()
{
	TestRefAndValue();

	return 0;
}

전 인용 의 효율 이 전 값 보다 훨씬 높다 는 것 을 알 수 있다.
다음 전송 값 반환 과 전송 참조 반환 비교

#include<iostream>
#include<time.h>
using namespace std;

struct A { int a[10000]; };

A a;
//    
A TestFunc1() { return a; }
//     
A& TestFunc2() { return a; }

void TestReturnByRefOrValue()
{
	//             
	size_t begin1 = clock();
	for (size_t i = 0; i < 100000; ++i)
		TestFunc1();
	size_t end1 = clock();

	//              
	size_t begin2 = clock();
	for (size_t i = 0; i < 100000; ++i)
		TestFunc2();
	size_t end2 = clock();

	//                
	cout << "TestFunc1 time:" << end1 - begin1 << endl;
	cout << "TestFunc2 time:" << end2 - begin2 << endl;
}


int main()
{
	TestReturnByRefOrValue();

	return 0;
}

전 인용 반환 의 효율 을 알 수 있 는데,전 값 보다 훨씬 낫다.
따라서 인용 을 전달 할 수 있 을 때 인용 을 전달 해 야 합 니 다.효율 이 더욱 높 지만 일부 변 수 는 인용 을 전달 할 수 없고 함수 가 나 오 면 스 택 프레임 이 소각 되면 경 계 를 넘 어 방문 할 수 있 습 니 다.
포인터(주소)와 인용 의 차이
문법 개념 에서 인용 은 하나의 별명 으로 독립 된 공간 이 없고 그 인용 실체 와 같은 공간 을 공용 한다.
밑바닥 실현 에 있어 서 인용 과 주 소 는 같 고 밑바닥 실현 에 있어 서 실제 적 으로 공간 이 있다.왜냐하면 인용 은 지침 방식 에 따라 이 루어 지기 때문이다.

#include<iostream>
#include<time.h>
using namespace std;

int main()
{
	int a = 10;

	//     ,   a          ,      
	int& ra = a;
	ra = 20;

	//     ,     pa    ,  4   ,  a   
	int* pa = &a;
	*pa = 20;

	int b = 10;
	int*& rpa = pa;
	rpa = &b;

	return 0;
}

인용 과 지침 이 어 셈 블 리 실현 에 있어 서 동일 하 다 는 것 을 알 수 있다.그렇다면 그들의 효율 도 마찬가지다.
포인터 와 인용의 차이 점:
  • 인용 은 정의 할 때 초기 화 되 어야 합 니 다.포인터 가 요구 하지 않 았 습 니 다
  • 초기 화 시 하나의 실 체 를 인용 한 후 다른 실 체 를 인용 할 수 없습니다.지침 은 언제든지 같은 유형의 실 체 를 가리 킬 수 있 습 니 다
  • NULL 참조 가 없 지만 NULL 포인터
  • sizeof 에서 의미 가 다 릅 니 다.인용 결 과 는 인용 형식의 크기 이지 만 주소 공간 이 차지 하 는 바이트 갯 수(32 비트 플랫폼 에서 4 개의 바이트)
  • 인용 추가 즉 인용 실체 증가 1,포인터 추가 즉 포인터 가 한 유형의 크기 로 뒤로 이동 합 니 다
  • 다단 계 지침 이 있 지만 다단 계 인용 이 없습니다
  • 실체 에 접근 하 는 방식 이 다 르 기 때문에 지침 은 명시 적 으로 인용 해 야 합 니 다.컴 파일 러 자체 처리
  • 포인터 보다 인용 이 안전 합 니 다.
  • 총결산
    여기 서 C++의 전송 값,전송 주소 와 전송 참조 차이 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 관련 C++전송 값,전송 주소 와 전송 참조 차이 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 많은 지원 을 바 랍 니 다!

    좋은 웹페이지 즐겨찾기