我们拥有的信息:
1)定义数组a[1000]
,a
是指针地址。
2)
void swap(int &c, int &b)
{
c=c+b;
b=c-b;
c=c-b;
}
// this is a method of swapping two variables without using temp variable.
// We use call by reference for the swap to actually take place in memory.
现在,当我为这两个条目调用此函数时说a[i],a[j]
...会发生什么?由于C / C ++的某些内部构造,函数是否接收到数组的两个单元格的地址,或者它是否接收指向a[i]
和a[j]
的指针的地址?
答案 0 :(得分:2)
a[i]
评估对i
元素的引用。它相当于*(a+i)
,其中a+i
是指向i
元素的指针。
内部的引用工作如何定义实现(你不应该关心),但大多数(所有)编译器在内部使用指针。在这种情况下,它们将指向数组中的两个元素。
答案 1 :(得分:2)
我会在场景后面说它会收到a[i]
和a[j]
的指针。
在以下两个程序上运行g++ -S
会产生相同的结果:
#include<iostream>
extern "C" void swap(int&c,int&b){
c=c+b;
b=c-b;
c=c-b;
}
int main(){
int*a=new int[1000];
a[10]=10;
a[42]=42;
swap(a[10],a[42]);
std::cout << a[10] << " " << a[42] << std::endl;
delete[] a;
return 0;
}
和
#include<iostream>
extern "C" void swap(int*c,int*b){
*c=*c+*b;
*b=*c-*b;
*c=*c-*b;
}
int main(){
int*a=new int[1000];
a[10]=10;
a[42]=42;
swap(a+10,a+42);
std::cout << a[10] << " " << a[42] << std::endl;
delete[] a;
return 0;
}
我使用extern "C"
能够diff
输出,否则错位不同。
旁注,当您写下时,例如a+42
考虑到a+sizeof(int)*42
是指向a
的指针,编译器会将地址计算为int
。此特定示例在生成的程序集源中显示为addl $168, %eax
。
答案 2 :(得分:1)
A)C和C ++是两种不同的语言。给定swap(int &c, int &b)
方法定义,它是C ++
B)因为它是C ++并且您传递了引用,所以您获得了对数组元素的引用(在内存中位于a + i
)
如果这是C,你会将你的函数定义为swap(int *c, int *d)
并且你将传递指针a + i
,因为数组会自动降级到指针。
答案 3 :(得分:1)
首先,你的交换函数是一个坏主意,因为总和的值可能会溢出。只需使用临时变量。
当你调用swap(a [i],a [j])时,函数的参数是指向内存位置a [i]和[j]的两个指针。指针包含两个int的地址。函数swap()将没有两个int的概念在同一个数组中。
将c和d声明为引用类似于传递指针,但是,您只能使用存储在此内存位置的值(相当于取消引用指针),但不能更改指针指向的地址。
答案 4 :(得分:1)
- 定义数组
醇>a[1000]
,a
是指针地址。
不,不是。 a
是一个数组。在许多情况下,它衰减指向第一个元素的指针,但它不是指针的地址(当然,除非你创建了一个指针数组)。
答案 5 :(得分:1)
只有当数字的总和在值的范围内时,交换两个没有临时数的数字的想法才有效;一个int可以保持。(通常是幂(2,sizeof(int)))。否则将发生溢出。 来到这个问题,
int *a=new int;
a[1000];// if i have understood your question then....
正如你在这里提到的那样 A 是一个指针而 A [i]是由 A 作为基地形成的数组。 在c中,当你在内部说p [i]时,它会转换为*(p + i),其中p是基址。类似地,当你传递值的引用地址时,传递。
注意:引用是隐式常量,引用必须在声明时赋予值。
引用就像一个隐式解引用的const指针。传递引用而不是指针是安全的,因为使用指针可能会导致段错误。(没有动态分配内存)
答案 6 :(得分:0)
a[i]
代表值,因此&a[i]
= a + i
将在内部传递。同样适用于a[j]
。