목차
인용하다
1. 소개
인생에서 우리는 또한 일부 학생들에게 별명을 붙일 수 있습니다.예를 들어 "장뢰"를 예로 들면 "장삼사"라고 부를 수 있습니다.이 별명을 부르면 자연스럽게 "장뢰", "장삼사" 는 Zhang Lei의 별칭이며 인용문은 다음과 같이 간단한 방식으로 이해할 수 있습니다. 문법적 수준에서 인용문은 별칭입니다 .
2. C++에서 더 번거로운 연산자
C++에서 * 및 &는 여러 가지 의미를 가지며 사용 조건에 따라 다른 의미를 갖습니다.
*
int *p = &a; /1.指针
a = a * b; /2.乘法
*p = 100; /3.指向
&
int c = a&b; /1.位运算 转换为二进制
int *p = &a; /2.取地址
int a = 100;
int & ar = a; /3.引用
3. 참조의 정의
참조는 변수의 새로운 정의가 아니라 기존 변수의 별칭입니다 컴파일러는 참조 변수에 대한 메모리 공간을 열지 않으며 참조 변수와 동일한 메모리 공간을 공유합니다.
형식은 다음과 같습니다 .
유형 및 참조 변수 이름(객체 이름) = 참조 엔터티
여기의 공백은 선택 사항입니다.
- 다음과 같이 & 기호 앞뒤에 공백이 있을 수 있습니다. int & ra=a;
- & 기호는 다음과 같이 유형 옆에 있습니다. int& ra=a;
- & 기호는 다음과 같이 참조 이름 옆에 있습니다. int &ra=a;
int main()
{
int a =100; \\定义变量名
int b = a;\\将a的值赋给变量
int &c = a;\\引用 将c作为a的别名 c11中成为左值引用
return 0;
}
여기서 그것은 a와 c라는 두 개의 이름을 갖는 개체에 해당하며, 이 공간에서 새로운 공간을 열지 않습니다.
4. 인용의 특징
- 참조를 정의할 때 초기화해야 함
- null 참조 없음
- 2차 인용이란 없다.
- 변수는 여러 참조를 가질 수 있습니다(여러 별칭이 있는 변수와 동일하며 가능함).
설명:
int main()
{
int a = 10;
int& b = a;
int& x;
int& y = NULL;
int&& c = a;
}
요약:
참조 자체는 변수이지만 이 변수는 또 다른 변수이자 별칭일 뿐이며 메모리 공간을 차지하지 않으며 포인터가 아닙니다! 그냥 별칭!
5. 포인터와 참조 비교
포인터를 사용하여 두 개의 정수 값을 교환하기 위해 스왑 함수를 예로 들어 보겠습니다
.
int my _swap (int*ap, int*bp)
{
assert(ap != NULL && bp != NULL);
int tmp = *ap;*ap = *bp;*bp = *ap;
}
int main()
{
int x = 10, y = 20;
my_swap{
&x,&y);
cout<< "x = " << x << " y = " << y << endl;
return 0;
}
참조를 사용하여 두 포인터를 교환합니다.
void my_swap (int& a,int& b)
{
int tmp = a;a = b;
b = tmp;
}
int main ()
{
int x = 10, y = 20;my_swap(x,y) ;
cout << " x = " << x<< " y = " << y << endl;
return 0;
}
형식 매개변수가 포인터일 때: 첫 번째 문장을 단언해야 하고 비어 있는지 판단해야 하며, 포인터를 사용할 때는 다음 사항에 주의해야 합니다.와일드 포인터,널 포인터,무효화 포인터.
참조를 사용할 때 NULL 참조가 없고 null을 판단할 필요가 없으며 포인터보다 안전합니다.
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
所以:能不用指针就尽量不要使用指针!
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
6. 참조와 포인터의 차이점( 강조 )
1. 문법적 차이
- 문법 규칙에서 포인터 변수는 인스턴스(변수 또는 개체)의 주소를 저장하고
참조는 인스턴스의 별칭입니다. - 프로그램은 포인터 변수에 대한 메모리 영역을 할당하고 참조에 대한 메모리 영역을 할당하지 않습니다.
int main()
{
int a = 10;
int* ip = &a;
int& b = a; \\b是a的别名 并没有分配新的空间
}
- 역참조는 포인터를 사용하기 전에 "*"를 추가하는 것으로 참조를 직접 사용할 수 있습니다.
int main()
{
int a = 10;
int* ip = &a;
int& b = a;
*ip = 100;//对于指针使用加“*”
b = 200; //引用不需要“*”
}
- 포인터 변수의 값은 다른 인스턴스의 주소를 저장하기 위해 변경될 수 있으며
참조는 정의될 때 초기화되며 이후에 변경할 수 없습니다(다른 인스턴스에 대한 참조일 수 없음).
int main()
{
int a = 10,b = 20;
int* ip = &a;
ip = &b ;
int& c = a;
c = b; //b的值给c实则是把b的值给a,将a的值改为20
}
- 포인터 변수의 값은 비어 있을 수 있으며(NULL, nullptr) null 참조가 없습니다.
- 포인터 변수를 형식 매개변수로 사용하는 경우 유효성 검사(NULL 판단)가 필요하며
참조는 NULL 판단이 필요하지 않습니다. - 포인터 변수에 "sizeof"를 사용하면 포인터 변수의 크기를 가져오고
참조 변수에 "sizeof"를 사용하면 변수의 크기를 가져옵니다.
int main()
{
double dx = 10;
double* dp = &dx;
double& a = dx;
printf("sizeof(dp):%d\n", sizeof(dp));
printf("sizeof(a):%d", sizeof(a));
}
작업 결과:
-
이론적으로 포인터 수준의 수에는 제한이 없지만 참조 수준은 하나뿐입니다.
즉, 참조에 대한 참조는 없지만 포인터에 대한 포인터는 있을 수 있습니다. -
++참조는 ++포인터와 다른 효과를 가집니다.
예를 들어 ++ 작업 측면에서:
int main()
(
int ar[5] = {
1,2,3,4,5 };
int* ip = ar; //数组首元素地址
int& b = ar[O]; //数组首元素的别名叫b
++ip; //由0下标的地址指向1下标的地址
++b; //由0下标指向1下标
}
- 참조에 대한 작업은 참조된 엔터티(변수 또는 개체)에 직접 반응합니다.
포인터 변수에 대한 작업은 가리키는 엔터티(변수 또는 개체)의 내용을 변경하는 대신 포인터 변수가 다음 엔터티(변수 또는 개체)의 주소를 가리키도록 합니다.
int main()
(
int ar[5] = {
1,2,3,4,5 };
int* ip = ar; //数组首元素地址
int& b = ar[O]; //数组首元素的别名叫b
++(*ip); //值由1>>2
(*ip)++; //所有表达式结束后 进行++
//有括号 先取ip的值与*结合 然后++为所指之物的++
int x = *ip++;
//没有括号 先将ip的值取出 与*结合 把所指之物取出(此时已与*结合完) 然后将ip取出进行++ ++后的值回写给ip 将值存储到x中
//通过()提高了优先级
}
-
함수의 지역 변수 또는 개체는 참조 또는 포인터로 반환할 수 없습니다.
변수의 수명이 함수의 영향을 받지 않는 경우 주소를 반환할 수 있습니다.
2. 조립 수준의 차이점
어셈블리 수준에서 참조는 포인터이지만 일반 포인터가 아니라 포인터의 구문 슬롯이며 일반 포인터로 간주할 수도 있습니다 .
int main()
{
int a = 10;
int* ip = &a;
int& x = a;
*ip = 100;
x = 200;
}
7. 참조의 기타 용도
- 자주 인용:
상수 참조는 실제로 일반 변수, 상수 또는 리터럴 상수를 참조할 수 있는 범용 참조입니다 .
(1) 일반 변수 참조
int main()
{
int a = 10;
int & b = a;
const int& c = a;
b += 10;
a += 10;
c += 10;
return 0;
}
이 오류 문제의 경우: c는 수정할 수 없기 때문에
(2) 참조 상수
int main()
{
int a = 10;
const int b =20;
int& x = a;
int& y = b; //error 不安全
const int& y = b; //ok
const int& z =10; //ok
return 0;
}
(3) 인용 리터럴 상수
리터럴 상수를 참조할 때 두 단계로 나뉘는데, 먼저 실제 리터럴 상수를 참조하는 대신 임시를 참조하도록 임시를 정의합니다 10.
int main()
{
int a = 10;
const int& z =10; //ok
//int tmp =10;
//const int &z = tmp;
return 0;
}
- 배열 참조
배열을 참조할 때 배열의 크기를 알아야 합니다.
int main()
{
int a = 10;
int b = 10;
int ar[5] = {
1,2,3,4,5 };
int& x = ar[0]; //ok
int(&x)[5] = ar; //ok 没有[5]无法编译通过
return 0;
}
- 포인터 참조
참조가 변수이므로 포인터 변수에 별칭을 지정할 수도 있습니다.
int main()
{
int a = 100;
int *p = &a;
int * &rp = p;
cout << a << endl;
cout << *p << endl;
cout << *rp << endl; //这里为什么要将*放在前面,因为p的类型是 int * 作为一个整体哦!!
cout << p << endl;
cout << rp << endl;
getchar();
return 0;
}
/*
100
100
100
012FF84C
012FF84C
*/
여기에서 포인터 변수 p가 참조(별칭) rp와 정확히 동일하다는 것을 발견했습니다. 그러나 참조의 목적이 포인터의 목적과 유사하기 때문에 일반적으로 포인터에 별칭을 지정할 필요가 없습니다.