Índice
citar
1. Introdução
Na vida, também podemos dar apelidos a alguns alunos. Tomemos "Zhang Lei" como exemplo, podemos chamá-lo de "Zhang Sanshi". Quando chamamos esse apelido, naturalmente pensaremos em "Zhang Lei", "Zhang Sanshi". é o pseudônimo de Zhang Lei, e a citação pode ser entendida desta maneira simples: no nível gramatical, uma citação é um pseudônimo .
Dois. Os operadores mais problemáticos em C++
* e & em C++ têm vários significados e têm significados diferentes sob diferentes condições de uso:
*
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. Definição de referência
Uma referência não é uma nova definição de uma variável, mas um alias para uma variável existente.O compilador não abrirá espaço de memória para a variável de referência e compartilhará o mesmo espaço de memória com a variável referenciada.
O formato é o seguinte :
Nome da variável de tipo e referência (nome do objeto) = entidade de referência
Observe que o espaço aqui é opcional, ou seja
- Pode haver um espaço antes e depois do símbolo &; como segue: int & ra=a;
- O símbolo & está ao lado do tipo, como segue: int& ra=a;
- O símbolo & fica ao lado do nome da referência, como segue: int &ra=a;
int main()
{
int a =100; \\定义变量名
int b = a;\\将a的值赋给变量
int &c = a;\\引用 将c作为a的别名 c11中成为左值引用
return 0;
}
Aqui equivale a uma entidade tomando dois nomes como a e c, e não abre um novo espaço neste espaço.
4. Características das citações
- Deve ser inicializado ao definir uma referência
- sem referências nulas
- Não existe citação secundária
- Uma variável pode ter várias referências (é equivalente a uma variável com vários aliases, o que é possível)
Explicação:
int main()
{
int a = 10;
int& b = a;
int& x;
int& y = NULL;
int&& c = a;
}
Resumindo:
a referência em si é uma variável, mas esta variável é apenas mais uma variável e um alias, não ocupa espaço na memória, não é um ponteiro! Apenas um pseudônimo!
5. Comparando ponteiros e referências
Vamos usar a função swap como exemplo
para trocar dois valores inteiros usando ponteiros:
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;
}
Troque dois ponteiros usando referências:
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;
}
Quando o parâmetro formal é um ponteiro: a primeira frase deve ser afirmada, e deve-se julgar se está vazia; e ao usar ponteiros, precisamos prestar atenção: se éponteiro selvagem,Ponteiro nulo,ponteiro de invalidação.
Quando usamos referências, não há referência NULL, não há necessidade de julgar null e é mais seguro que ponteiros
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
所以:能不使用指针就尽量不要使用指针!
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Seis. A diferença entre referências e ponteiros ( ênfase )
1. Diferenças no nível gramatical
- Em termos de regras gramaticais, uma variável de ponteiro armazena o endereço de uma instância (variável ou objeto);
uma referência é um alias de uma instância. - O programa aloca regiões de memória para variáveis de ponteiro; ele não aloca regiões de memória para referências.
int main()
{
int a = 10;
int* ip = &a;
int& b = a; \\b是a的别名 并没有分配新的空间
}
- Desreferenciar é adicionar "*" antes de usar o ponteiro; a referência pode ser usada diretamente.
int main()
{
int a = 10;
int* ip = &a;
int& b = a;
*ip = 100;//对于指针使用加“*”
b = 200; //引用不需要“*”
}
- O valor da variável ponteiro pode ser alterado para armazenar os endereços de diferentes instâncias;
a referência é inicializada quando é definida e não pode ser alterada posteriormente (não pode ser uma referência a outras instâncias).
int main()
{
int a = 10,b = 20;
int* ip = &a;
ip = &b ;
int& c = a;
c = b; //b的值给c实则是把b的值给a,将a的值改为20
}
- O valor de uma variável de ponteiro pode estar vazio (NULL, nullptr); não há referências nulas.
- Quando uma variável de ponteiro é usada como um parâmetro formal, sua validade precisa ser testada (julgamento NULL); as
referências não precisam ser julgadas NULL. - Usar "sizeof" em uma variável de ponteiro obtém o tamanho da variável de ponteiro;
usar "sizeof" em uma variável de referência obtém o tamanho da variável.
int main()
{
double dx = 10;
double* dp = &dx;
double& a = dx;
printf("sizeof(dp):%d\n", sizeof(dp));
printf("sizeof(a):%d", sizeof(a));
}
resultado da operação:
-
Em teoria, não há limite para o número de níveis de ponteiros, mas há apenas um nível de referências.
ou seja, não há referências a referências, mas pode haver ponteiros para ponteiros. -
++referências têm efeitos diferentes de ++ponteiros.
Por exemplo, em termos de operações ++:
int main()
(
int ar[5] = {
1,2,3,4,5 };
int* ip = ar; //数组首元素地址
int& b = ar[O]; //数组首元素的别名叫b
++ip; //由0下标的地址指向1下标的地址
++b; //由0下标指向1下标
}
- As operações em referências reagem diretamente à entidade referenciada (variável ou objeto).
A operação na variável ponteiro fará com que a variável ponteiro aponte para o endereço da próxima entidade (variável ou objeto); em vez de alterar o conteúdo da entidade apontada (variável ou objeto).
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中
//通过()提高了优先级
}
-
Variáveis locais ou objetos em funções não podem ser retornados por referência ou ponteiro.
O endereço pode ser retornado quando o tempo de vida da variável não é afetado pela função
2. Diferenças no nível de montagem
No nível do assembly, uma referência é um ponteiro, mas uma referência não é um ponteiro comum, é um slot de sintaxe para ponteiros e também pode ser considerado um ponteiro comum.
int main()
{
int a = 10;
int* ip = &a;
int& x = a;
*ip = 100;
x = 200;
}
7. Outros usos de referências
- Frequentemente citado:
Uma referência constante é, na verdade, uma referência universal que pode se referir a variáveis comuns, constantes ou constantes literais .
(1) Refere-se a variáveis comuns
int main()
{
int a = 10;
int & b = a;
const int& c = a;
b += 10;
a += 10;
c += 10;
return 0;
}
Para este problema de erro: porque c não é modificável
(2) constante de referência
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) Aspas constantes literais
Ao referenciar uma constante literal, ela é dividida em duas etapas. Primeiro, defina um temporário para referir-se ao temporário em vez de referenciar a constante literal real 10.
int main()
{
int a = 10;
const int& z =10; //ok
//int tmp =10;
//const int &z = tmp;
return 0;
}
- referência de matriz
Ao referenciar uma matriz, o tamanho da matriz deve ser conhecido
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;
}
- referência do ponteiro
Como a referência é uma variável, também posso atribuir um alias à variável do ponteiro
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
*/
Descobrimos que a variável de ponteiro p aqui é exatamente a mesma que sua referência (alias) rp. Mas como o propósito de uma referência é semelhante ao de um ponteiro, geralmente não há necessidade de criar um alias para o ponteiro.