简体   繁体   English

阵列交换功能

[英]Swap function for Array

Information that we have: 我们拥有的信息:

1) defining an array a[1000] , a is the pointer address. 1)定义数组a[1000]a是指针地址。

2) 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.

Now , when i call this function for a's two entries say a[i],a[j] ...what happens ?? 现在,当我为a的两个条目调用此函数时,说a[i],a[j] ...会发生什么情况? Does the function receive the address of the two cells of the array due to some internal construct of C/C++ or does it receive the address of the pointers pointing at a[i] and a[j] ? 该函数是否由于C / C ++的内部构造而接收到数组两个单元的地址,还是接收到指向a[i]a[j]的指针的地址?

a[i] evaluates to a reference to the i th element. a[i]计算对第i个元素的引用。 It is the equivalent of *(a+i) , where a+i is a pointer to the i th element. 它等效于*(a+i) ,其中a+i是指向第i个元素的指针。

How references work internally is implementation defined (you shouldn't care), but most(all) compilers use pointers internally. 引用在内部如何工作是由实现定义的(您不必在意),但是大多数(所有)编译器在内部使用指针。 In this case they would be pointers to the two elements in the array. 在这种情况下,它们将是指向数组中两个元素的指针。

I'd say that behind the scene it would receive pointers to a[i] and a[j] . 我想说的是,在幕后它将收到指向a[i]a[j]指针。

Running g++ -S on the following two programs produces identical results: 在以下两个程序上运行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;
}

and

#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;
}

where I used extern "C" to be able to diff the outputs, otherwise the mangling differs. 我使用extern "C"diff输出,否则处理方式有所不同。

Side note, when you write eg a+42 the compiler will calculate the address as a+sizeof(int)*42 , taking into account that a is a pointer to int . 旁注,当您编写例如a+42 ,考虑到a是指向int的指针,编译器会将地址计算为a+sizeof(int)*42 This particular example shows up as an addl $168, %eax in the generated assembly source. 这个特定的示例在生成的程序集源中显示为addl $168, %eax

A) C and C++ are two different languages. A)C和C ++是两种不同的语言。 Given your swap(int &c, int &b) method definition, it's C++ 给定您的swap(int &c, int &b)方法定义,它就是C ++

B) Because it's C++ and you're passing references , you get a reference to the array element (which in memory is located at a + i ) B)因为它是C ++,并且您正在传递引用 ,所以您获得了对数组元素的引用(在内存中位于a + i

If this were C you would have defined your function as swap(int *c, int *d) and you'd be passing the pointer a + i because array degrade to pointers automatically. 如果是C,则将您的函数定义为swap(int *c, int *d)并且将传递指针a + i因为数组自动降级为指针。

First of all, your swap function is a bad idea as the value of the sum might overflow. 首先,交换函数是个坏主意,因为总和的值可能会溢出。 Just use a temp variable. 只需使用一个临时变量。

When you call swap(a[i], a[j]) the arguments to the function are two pointers to the memory locations a[i] and a[j]. 当调用swap(a [i],a [j])时,函数的参数是指向存储位置a [i]和a [j]的两个指针。 The pointers contain the addresses of the two ints. 指针包含两个int的地址。 The function swap() will have no concept of the two ints being in the same array. 函数swap()不会将两个int放在同一数组中。

Declaring c and d as references is similar to passing a pointer, however, you can only work with the values stored in this memory location (equivalent to dereferencing the pointer) but not change the address the pointer points to. 将c和d声明为引用类似于传递指针,但是,您只能使用存储在此内存位置中的值(等效于取消引用指针),而不能更改指针指向的地址。

  1. defining an array a[1000] , a is the pointer address. 定义数组a[1000]a是指针地址。

No it isn't. 不,不是。 a is an array. a是一个数组。 In many cases it decays to a pointer to the first element, but it is not the address of a pointer (unless you made an array of pointers, of course). 在许多情况下,它会衰减到指向第一个元素的指针,但它不是指针的地址(当然,除非您创建了一个指针数组)。

The idea of swapping two numbers without temp works well only if sum of numbers is in the range of value ;a int can hold.(typically power(2,sizeof(int))).or else overflow will occur. 仅当数字之和在值范围内时才可以交换两个不带temp的数字,这种想法很好用;一个int可以保存。(通常为power(2,sizeof(int))),否则会发生溢出。 Coming to the question, 谈到这个问题,

int *a=new int;
a[1000];// if i have understood your question then....

As mentioned by you here A is a pointer and A [i] is array formed with A as base address. 如您在这里所述, A是一个指针, A [i]是一个A为基地址形成的数组。 In c when you say p[i] internally it get converted as *(p+i) where p is base address.similarly when you pass by reference address of value is passed. 在c中,当您内部说p [i]时,它会转换为*(p + i),其中p是基地址。类似地,当您通过值的引用地址时,也会被传递。

Note :References are implicitly constant ,references must be given value upon declaration. 注意:引用是隐式常量,引用必须在声明时赋予值。

References acts like a const pointer that is implicitly de-referenced.It is safe to pass references than that of pointers as using pointer may lead to segfaults.(where there is no dynamic allocation of memory) 引用的行为就像隐式取消引用的const指针一样,传递引用比使用指针安全,因为使用指针可能会导致段错误(没有动态分配内存的地方)

a[i] represents the value so &a[i] = a + i will be passed (internally). a[i]代表值,所以&a[i] = a + i将被(内部)传递。 Likewise for a[j] . 同样对于a[j]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM