问题
I am trying to grasp come concepts related to pointers and references. In the code snippet below, I call function shifting() several times from a for loop while iterating a linked list. With each iteration, int *ptr and int count are changed and passed to the function shifting(). Also, some other pointers and integer variables are passed by reference.
Doubts:
can I assign pointer references like shown in shifting() function? Same question for integer val references.
What is going on in the background? I read that references cannot be re-assigned. Is this not the case here every time shifting() is called?
please note, *ptr and count are NOT passed by reference. They are only to be read.
void shifting(int const * ptr, int const * &ptr6, int const * &ptr7, int const * &ptr8,
int count, int &val6, int &val7, int &val8)
{
ptr8 = ptr7; val8 = val7;
ptr7 = ptr6; val7 = val6;
ptr6 = ptr; val6 = count;
}
int main()
{
int const *ptr6 = NULL; int val6 = 0;
int const *ptr7 = NULL; int val7 = 0;
int const *ptr8 = NULL; int val8 = 0;
int count = 0;
// myList: a linked-list
// front(): gives first element of list
// back(): gives last element of list
// nextElement(): gives next element of list
for (int *ptr = myList.front(); ptr != myList.back(); ptr = nextElement();)
{
count++;
shifting(ptr, ptr6, ptr7, ptr8, count, val6, val7, val8);
}
}
EDIT: I tried the above example (after posting here) with only integer part as shown below:
#include <iostream>
using namespace std;
void shifting( int i, int &val6, int &val7, int &val8 )
{
val8 = val7;
val7 = val6;
val6 = i;
}
int main()
{
int val6 = 0;
int val7 = 0;
int val8 = 0;
for (int i = 1; i <= 10; i++)
{
shifting(i, val6, val7, val8);
cout <<"i: "<<i<<" val6: "<<val6<<" val7: "<<val7<<" val8: "<<val8<<endl;
}
return 0;
}
I got this output as below. How come references are being re-assigned??? I read they are not supposed to reassign.
i: 1 val6: 1 val7: 0 val8: 0
i: 2 val6: 2 val7: 1 val8: 0
i: 3 val6: 3 val7: 2 val8: 1
i: 4 val6: 4 val7: 3 val8: 2
i: 5 val6: 5 val7: 4 val8: 3
i: 6 val6: 6 val7: 5 val8: 4
i: 7 val6: 7 val7: 6 val8: 5
i: 8 val6: 8 val7: 7 val8: 6
i: 9 val6: 9 val7: 8 val8: 7
i: 10 val6: 10 val7: 9 val8: 8
回答1:
- can I assign pointer references like shown in shifting() function? Same question for integer val references.
Yes. But when you do so, you are assigning to the referent, not the reference.
What is going on in the background?
This is what's (effectively) going on in the background. That is to say, if you wanted to achieve the same effect without references, you might do this:
void shifting(int const * ptr, int const ** ptr6, int const ** ptr7, int const ** ptr8,
int count, int* val6, int *val7, int *val8)
{
*ptr8 = *ptr7; *val8 = *val7;
*ptr7 = *ptr6; *val7 = *val6;
*ptr6 = ptr; *val6 = count;
}
And at the place where you call it:
shifting(ptr, &ptr6, &ptr7, &ptr8, count, &val6, &val7, &val8);
I read that references cannot be re-assigned.
That is correct. Although I prefer the term re-bound. You can do what looks like an assignment to a reference. But that is actually an assignment to the referent. In fact, after a reference is created, thereafter, its name acts as an alias to the referent. Any operation on the reference (with the exception of decltype) is as if done on the referent.
Is this not the case here every time shifting() is called?
No. When you use the assignment operator on a reference, you are actually assigning to the referent, not the reference.
Your example is extremely convoluted, perhaps something simpler will clear things up.
int a = 0;
int b = 77;
int& ra = a; // ra is a reference to a, and always will be
int& rb = b; // rb is a reference to b, and always will be
ra = b; // ra is still a reference to a, but now a == 77
ra = 999; // now a == 999
rb = ra; // rb is still a reference to b, but now b == 999
To further clarify, the above example is exactly equivalent to this:
int a = 0;
int b = 77;
a = b;
a = 999;
b = a;
Or this example using pointers:
int a = 0;
int b = 77;
int* pa = &a; // pa is a pointer to a, this can change, but won't in this example
int* pb = &b; // pb is a pointer to b, this can change, but won't in this example
*pa = b; // pa is still a pointer to a, but now a == 77
*pa = 999; // now a == 999
*pb = *pa; // pb is still a pointer to b, but now b == 999
回答2:
I think you may partly be confusing yourself by re-using variable names between the function and the caller: For example, within shifting val6 is a local variable, bound to whatever it was called with, which just happens to be an external variable with the same name.
#include <iostream>
void test(int& i) {
std::cout << "test/i = " << i << '\n';
}
int main() {
int i = 1;
int j = 42;
test(i);
test(j);
}
This outputs (see http://ideone.com/lRNINP)
test/i = 1
test/i = 42
The significance of being a local reference is that it goes away at the end of the function iteration and is reformed with the new arguments at the next iteration.
I got this output as below. How come references are being re-assigned???
They aren't, the values are simply shifting as your function appears to aim to do: (see http://ideone.com/oCmOPk)
#include <iostream>
int main() {
int i = 0;
int& ir = i; // not an assignment, a binding
ir = 1; // pass '1' thru 'ir' to 'i'.
std::cout << "ir " << ir << ", i " << i << "\n";
int j = 0;
int& jr = j;
jr = 42; // pass '42' thru 'jr' to 'j'
std::cout << "jr " << jr << ", j " << j << "\n";
ir = jr; // pass the *value* of 'jr' thru 'ir' to 'i'
j = 99;
// if ir is rebound to jr, both of these will be 99.
std::cout << "ir " << ir << ", i " << i << "\n";
std::cout << "jr " << jr << ", j " << j << "\n";
}
Output:
ir 1, i 1
jr 42, j 42
ir 42, i 42
jr 99, j 99
来源:https://stackoverflow.com/questions/36826763/pointers-passed-by-reference-updated-with-every-loop-iteration-sanity-check