嗨,我是C++的新手,我已经写了一个选择排序程序,你能帮我说说为什么在交换函数中我们要放星星(*),在选择排序中我们应该用&; 在<
int newint = a;
a = b;
b = newint;
而不是:
int newint = *a;
*a = *b;
*b = newint;
主代码:
using namespace std;
void swap(int *a, int *b);
void selectionSort(int arr[], int size);
void printArray(int arr[], int size);
int main() {
int arr[] = {20, 12, 10, 15, 2};
int size = sizeof(arr) / sizeof(arr[0]);
selectionSort(arr, size);
cout << "Sorted array in Acsending Order:\n";
printArray(arr, size);
}
// ================================================
// swap function to swap two element of the array
void swap(int *a, int *b){
int newint = *a;
*a = *b;
*b = newint;
}
// ================================================
// the selection function made of two main loop
void selectionSort(int arr[], int size) {
for (int i = 0; i < size - 1; i++) {
int min = i;
for (int j = i + 1; j < size; j++) {
if (arr[j] < arr[min])
min = j;
}
swap(&arr[min], &arr[i]);
}
}
// ================================================
// print function to show the final result
void printArray(int arr[], int size) {
for (int i = 0; i < size; i++) {
cout << arr[i] << " ";
}
cout << endl;
}
指针是通过引用传递的,这意味着,如果您在函数中更改它,那么在函数调用之后它也会被更改。 如:
int a=5;
setTo6(&a);//Implementation: *a=6
//a=6
另一方面,所有其他不是指针的参数都是按值传递的。 这意味着,如果您在函数中更改它们,它不会在调用方端被更改。
int a=5;
setTo6ByValue(a);//Implementation: a=6
//a=5
因此,考虑这两个交换函数:(1)
void swap(int *a, int *b){
int newint = *a;
*a = *b;
*b = newint;
}
和(2)
void swap(int a, int b){
int newint = a;
a = b;
b = newint;
}
第一部会发生什么?
int a=5;//Address=0x1000
int b=6;//Address=0x1004
swap(&a,&b);
指针被传递给函数,之后,地址0x1000处的内容(指向a
的指针)被存储在newint
中。
*a=*b;
将地址0x1000
处的int设置为地址B
(0x1004)处的值。
*B=新的;
将地址0x1004
处的int设置为newINT
的值。
第二个会做什么?
int a=5;//Maybe in the r8 register
int b=6;//r9 register
swap(a,b);
我们将有以下汇编代码(确实未优化):
mov $5, %r8 //int a = 5
mov $6, %r9 //int b = 6
//Setup registers (https://stackoverflow.com/a/2538212/13912132)
mov %r8, %rdi
mov %r9, %rsi
call swap // swap(a,b)
....
swap:
mov %rdi, %rax //int newint=a
mov %rsi, %rdi //a=b
mov %rax, %rsi //b=newint
ret //Return to caller
它们不会被更改,因为您只更改了变量。
这两个概念称为按值调用和按引用调用。 这里进一步说明:https://www.guru99.com/call-by-value-vs-call-by-reference.html
a
和b
是指针,作为参数接收,传递它们的地址。 它们就像手指。 例如,你用手指指向一个值,我用手指指向另一个值。 当您打算交换我们所指向的内容时,那么您将需要指向我先前所指向的地方,而我将需要指向您先前所指向的地方。 你的建议是交换我们的手指。
或者,更严格地说:您需要交换指针所指向的值,而不是交换指针的内存位置。
另一个类比可以是地址。 你住在某个地址,我住在另一个地址。 如果我们交换地址,你就搬到我以前的地址,我就搬到你以前的地址。 但是我们并没有把我们住过的房子搬到新的住址。