Question about the efficiency of using an array or individual variables

In summary, the conversation discusses the efficiency of using array A[10] versus individual variables B(0..9) in a program. The individual variables may be faster due to their one-step access, while the array requires additional steps to access the desired value. The conversation also touches on the limitations of declaring arrays with a constant size and the use of vector as a workaround. Finally, the conversation explains the difference in initialization between {1} and {1, 1, 1, 1, 1, 1, 1, 1, 1, 1} for an array of boolean values.
  • #176
Mark44 said:
You've been told this several times. An address, currently, is an integer, but its type is not int! Until you come to terms with this, you aren't going to understand pointers.

Also, and I've said this before, addresses in the past were not integers.
Hardware and high-level language are two entirely different things.
This is a language most commonly used in firmware in hardware level.

When I said address is an integer, I meant it is a whole number, not a double. I know *ptr point to an address. I don't mean *ptr = x where x is an integer.

Or else why define int **pptr; and pptr = &ptr ? Maybe I should say address is a whole number like integer.
 
Technology news on Phys.org
  • #177
PeterDonis said:
Yes, you are. If you weren't, you wouldn't have asked the questions you asked in post #165.
#165 has nothing to do with integer, I just want to verify the data and pointer are destroy after exiting the function.
 
  • #178
yungman said:
This is a language most commonly used in firmware in hardware level.
I don't see how this is relevant to the discussion here about pointers.
yungman said:
When I said address is an integer, I meant it is a whole number, not a double.
That's not what you said in post #171, copied below

yungman said:
you can ONLY assign ADDRESS of variable/constant to a pointer eg. int *ptr; ptr = &var; where var can be int, double, const, char etc.

The only legitimate type for var is int, not double, char, or anything else.
 
  • #179
yungman said:
This is a language most commonly used in firmware in hardware level.

Not at all. Both C++ and C are used for all kinds of projects, many of them having no direct hardware interaction at all. The interpreters for high level languages like Python are written in C.
 
  • #180
yungman said:
#165 has nothing to do with integer, I just want to verify the data and pointer are destroy after exiting the function.

And you did that incorrectly, because you are still confused about how variable types and pointer types work in C and C++, because you are still hung up on actual memory addresses being "integers". Sure, they are "integers" in the sense that they are discrete--there are no fractions of address lines, as you say--but they are not "integers" as far as C and C++ are concerned, because pointers and integers are different types, and pointers to integers are a different type from pointers to floats, which are a different type from pointers to chars, etc.

Do you want to get unconfused or not?
 
  • #181
I am really not good in the terms and all that. Let me just say what I understand. If this still have problem, then I have to learn more:

1) int*ptr is a pointer that can only point to an address of an integer variable. ptr is the address, you can do ptr =&x where x is an integer. for double, const, you use: double dbt; double *ptr=&dbt etc.

2) for pointer to pointer. use int**pptr. pptr can only be address of a pointer. pptr cannot equal to &x. It's ok for pptr=&ptr. eg. int*ptr; int**pptr; pptr=&ptr; &ptr is the address of ptr.

I don't know why they use int**pptr. It is not ok to point to an integer variable. pptr has to be address of a pointer like ptr. Like it is legal to wtite pptr=&ptr.The confusion is I said address is an integer. This is NOT saying address is classified as int as you think in C++. All I am saying is address has to be a whole number, no fraction. It cannot even be -ve integer. You know there is a clear meaning of INTEGER outside of C++, that's what I was using for, not in terms of int in C++. Integer is just a whole number with no fraction, not int in C++.Don't read the other posts as I might said things wrong in terms of using names. If there is anything wrong with what I said here, let me know. to me, this is crystal clear now.
 
  • #182
yungman said:
int*ptr is a pointer that can only point to an address of an integer variable.

Yes.

yungman said:
for pointer to pointer. use int**pptr

No. For pointer to pointer to an int variable, use int** pptr. For a pointer to a pointer to a different type of variable, you would have to use the different type instead of int; so, for example, for a pointer to a pointer to a double variable, it would be double** pptr.

yungman said:
I don't know why they use int**pptr.

Because that is how to say "pointer to pointer to int" in C/C++. Each asterisk represents "pointer to". For a pointer to a pointer to some other type, you would say it differently, as above.

yungman said:
All I am saying is address has to be a whole number, no fraction.

We all know that. Continuing to belabor it as thought it were something the rest of us haven't grasped adds nothing whatever to the discussion; all it does is make us think that you haven't yet grasped the difference between "whole number, not a fraction" and "the C/C++ integer type".
 
  • Like
Likes yungman
  • #183
@yungman, there's no need to feel down
I said @yungman, pick yourself off the ground
I said @yungman, pointers won't make you frown
There's no need to be un-hap-py

It's fun to code using G-N-U C
It's fun to code using G-N-U C

Sorry. Needed to get that out of my system.
 
  • Like
Likes yungman
  • #184
PeterDonis said:
Yes.
No. For pointer to pointer to an int variable, use int** pptr. For a pointer to a pointer to a different type of variable, you would have to use the different type instead of int; so, for example, for a pointer to a pointer to a double variable, it would be double** pptr.
Because that is how to say "pointer to pointer to int" in C/C++. Each asterisk represents "pointer to". For a pointer to a pointer to some other type, you would say it differently, as above.
We all know that. Continuing to belabor it as thought it were something the rest of us haven't grasped adds nothing whatever to the discussion; all it does is make us think that you haven't yet grasped the difference between "whole number, not a fraction" and "the C/C++ integer type".
Ah, I see. If *ptr is an int. The pointer to pointer **pptr that point to ptr HAS to be int**pptr;. NOT THAT it is pointing to an int, just to acknowledge that it is pointing to a pointer that points to an int.

Thank you. That makes a whole lot of sense now. Again, the chapter say nothing about this and leave me hanging. this chapter is almost as bad as the other book I used to use.

I just want to clarify about what I said "integer". I knew very well address is an address. I just described address as whole number and the best fit term is just integer as common integer.
 
  • #185
Vanadium 50 said:
@yungman, there's no need to feel down
I said @yungman, pick yourself off the ground
I said @yungman, pointers won't make you frown
There's no need to be un-hap-py

It's fun to code using G-N-U C
It's fun to code using G-N-U C

Sorry. Needed to get that out of my system.
I was pulling hair for a day or so, but now I am happy and have fun again. Just kept at it, last night, it was a lightbulb moment, it's just that simple. Thanks to the people here, no thanks to the book.

What is G-N-U C?
 
  • #186
yungman said:
If *ptr is an int. The pointer to pointer **pptr that point to ptr HAS to be int**pptr;. NOT THAT it is pointing to an int, just to acknowledge that it is pointing to a pointer that points to an int.

Yes.
 
  • Like
Likes yungman
  • #187
PeterDonis said:
Yes.
I am happy camper now. Now I can move on. BUT, first, I am going to take it easy today, have a nice drink and relax! I was pulling hair for the last day! It's like what's wrong with me, it's right in front of my face and I just cannot connect them together.
 
  • #188
I am still experimenting with pointer to pointer. I don't understand why this program can still maintain the value of the local variable in the function after exiting:
C++:
// passing reference to pointer to function 2
#include <iostream>
using namespace std;void changeRvalue(int*&);

int main()
{
    int var = 23;
    int* ptr;
    ptr = &var;
    cout << " Before passing to function, *ptr = " << *ptr << "\n\n";
    changeRvalue(ptr);
    cout << " After passing to function, *ptr = " << *ptr << "\n\n";
    return 0;
}
void changeRvalue(int*& pp)
{
    int glov = 52;
    pp = &glov;
}

As you see line20, int glov = 52 is local variable in function changeRvalue. But when return to main and display *ptr, I still get *ptr = 52.

I thought the value would be destroyed after exiting the function?

Thanks
 
  • #189
yungman said:
I am still experimenting with pointer to pointer. I don't understand why this program can still maintain the value of the local variable in the function after exiting:

I thought the value would be destroyed after exiting the function?

Thanks

using a reference to a local variable is "undefined behaviour". https://en.wikipedia.org/wiki/Undefined_behavior
There are no guarantees about what will happen at all. non-C compilers won't allow this sort of thing.

After returning from your function the local variable probably won't be overwritten, but you should really not rely on this. If you use another function before you use *ptr you will likely overwrite this value.

I added cout << 1.0f; after the call to changevalue(), and I get *ptr = 9436264 (different values every time)
If you compile in release mode however, you still get 52 out. The compiler sees that you modify the same variable and just sends the number 52 to the output, so there's nothing on the stack to get overwritten.
 
  • Like
Likes yungman
  • #190
willem2 said:
using a reference to a local variable is "undefined behaviour". https://en.wikipedia.org/wiki/Undefined_behavior
There are no guarantees about what will happen at all. non-C compilers won't allow this sort of thing.

After returning from your function the local variable probably won't be overwritten, but you should really not rely on this. If you use another function before you use *ptr you will likely overwrite this value.

I added cout << 1.0f; after the call to changevalue(), and I get *ptr = 9436264 (different values every time)
If you compile in release mode however, you still get 52 out. The compiler sees that you modify the same variable and just sends the number 52 to the output, so there's nothing on the stack to get overwritten.
So just don't count on it. It just so happen the value in glov is not erased only, no guaranty.

Thanks
 
  • #191
I am still working on passing a reference of a pointer to function. I learn there are two ways to do that and are shown in the program below. I just want to verify I am correct:
C++:
#include <iostream>
using namespace std;
void changeRvalueA(int*&);// function receives a pointer of an address
void changeRvalueB(int**);// function receives a pointer to pointer
int main()
{
    int var = 23;
    int* ptrA;// pointer whose address to be passed
    ptrA = &var;// pointer pointing to address of var
    changeRvalueA(ptrA);// passing address of pointer ptrA
    cout << "     ptrA = " << ptrA <<  "\n\n";

    int* ptrB;// declare a pointer ptr
    int** pptrB = &ptrB;
    ptrB = &var; //ptr pointing to address var
    changeRvalueB(pptrB);// passing pointer of pointer pptrB.
    cout << "     pptrB = " << pptrB << "\n\n";
    return 0;
}
void changeRvalueA(int*& ppA)// receiving address for pointer ppA
{    cout << " ppA = " << ppA;    }

void changeRvalueB(int** ppB)// receiving pointer to pointer ppB.
{    cout << " ppB = " << ppB;    }

// ppA = 00FDF854  ptrA = 00FDF854        ppB = 00FDF83C  pptrB = 00FDF83C

As you can see, I have two separate ways, I labelled the first with names ended in "A", the second with names ended in "B". They look the same, but the idea is very different.

In A, The program passes the ADDRESS of the pointer ptrA. This is similar to passing by reference for variables to function.

In B, The program passes the pointer to pointer pptrB to the function. You can skip using pptrB by passing &ptrB instead in main. This is to save a line to declare pptrB = &ptrB.

I copied the result of running of the two in line 26.

Let me know whether I am correct in my analysis. If both are right, I much prefer using method A because it is exactly the same as passing variables by reference where only the address of the variable is passed to the function.

Thanks
 
  • #192
yungman said:
I am still working on passing a reference of a pointer to function. I learn there are two ways to do that and are shown in the program below. I just want to verify I am correct:
C++:
#include <iostream>
using namespace std;
void changeRvalueA(int*&);// function receives a pointer of an address
void changeRvalueB(int**);// function receives a pointer to pointer
int main()
{
    int var = 23;
    int* ptrA;// pointer whose address to be passed
    ptrA = &var;// pointer pointing to address of var
    changeRvalueA(ptrA);// passing address of pointer ptrA
    cout << "     ptrA = " << ptrA <<  "\n\n";

    int* ptrB;// declare a pointer ptr
    int** pptrB = &ptrB;
    ptrB = &var; //ptr pointing to address var
    changeRvalueB(pptrB);// passing pointer of pointer pptrB.
    cout << "     pptrB = " << pptrB << "\n\n";
    return 0;
}
void changeRvalueA(int*& ppA)// receiving address for pointer ppA
{    cout << " ppA = " << ppA;    }

void changeRvalueB(int** ppB)// receiving pointer to pointer ppB.
{    cout << " ppB = " << ppB;    }

// ppA = 00FDF854  ptrA = 00FDF854        ppB = 00FDF83C  pptrB = 00FDF83C

As you can see, I have two separate ways, I labelled the first with names ended in "A", the second with names ended in "B". They look the same, but the idea is very different.

In A, The program passes the ADDRESS of the pointer ptrA. This is similar to passing by reference for variables to function.

In B, The program passes the pointer to pointer pptrB to the function. You can skip using pptrB by passing &ptrB instead in main. This is to save a line to declare pptrB = &ptrB.

I copied the result of running of the two in line 26.

Let me know whether I am correct in my analysis. If both are right, I much prefer using method A because it is exactly the same as passing variables by reference where only the address of the variable is passed to the function.

Thanks

Have you learned about references in C++ yet? I don't think a reference in C++ is good to think of as an ADDRESS. In fact it would be much more correct to think of a pointer as an address. Rather, in (A) you are passing a reference (not address) to a pointer. In (B) you are passing a pointer to a pointer (which can be thought of as passing the address of an address).

This might be confusing because it seems you've been calling pointers references up to now (and there is some room for confusion about the difference in C++ anyways). It may also be confusing about the multiple meanings of symbols * and & in different contexts.

https://en.cppreference.com/w/cpp/language/reference

My feeling is in basic agreement with pbuk's post #160. The stuff you're doing now (the way you're using pointers) is more a C style of programming, and generally considered bad practice/style in C++.

Also as pbuk was alluding to, once you learn about classes and object oriented programming, if you start trying to write good code, you'll probably want to use a completely different approach to allocating memory. I usually follow RAII, which is an idiom to follow in order to better organize your use of manually dynamically allocated memory and to avoid making mistakes and causing bugs.

https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization

Anyway, once you understand pointers and references, then you should probably move on because you really have barely scratched the surface of C++, and mostly haven't even seen the ++ parts of C++ yet.

That's just my 2 cents.
 
Last edited:
  • Like
Likes yungman and pbuk
  • #193
yungman said:
C++:
void changeRvalueA(int*& ppA)// receiving address for pointer ppA
{    cout << " ppA = " << ppA;    }
In A, The program passes the ADDRESS of the pointer ptrA.
No, that's not what you're doing. the function parameter is of type reference to pointer to int. In all the C++ books I've seen over the years, I've never seen a single function with a parameter like this, which is a weird mixture of C notation (pointer parameter) and C++ (reference parameter). Since it's not shown in books, it's probably not a good thing to put in a real program.

Keep in mind that the & operator is used for three different things, so can be easily confused.
  1. Bitwise AND operator
    The expression 1 & 4 evaluates to 0.
  2. Address-of operator
    If var is declared as an int, the expression &var evaluates to the address of the first byte of the memory that contains var.
  3. Reference operator
    If a function's header is void func(int & val), this means that val is another name for whatever actual argument is used in the call to func().
As @Jarvis323 pointed out, your misuse of terminology by referring to pointers as references is preventing you from understanding that they aren't the same thing.

Before messing around with double indirection or combinations of pointers and references, spend some time working with single indirection parameters and reference parameters, separately.

Here's an example that shows the difference between a function with a pointer parameter and another with a reference parameter. Take a close look at the difference in how the two functions are called.
C++:
#include <iostream>
using std::cout;

void FuncPtr(int *);    // Prototype for a function with a pointer parameter
void FuncRef(int &);   // Prototype for a function with a reference parameter

int main()
{
    int x = 3;
    int y = 5;

    FuncPtr(&x);    // Note the difference in the semantics for the two functions
    FuncRef(y);

    cout << "New value for x: " << x << '\n';
    cout << "New value for y: " << y << '\n';
}

void FuncPtr(int* argPtr)
{
    *argPtr = 10;
}

void FuncRef(int & argRef)
{
    argRef = 10;
}
Although the variables x and y start off with different values, they both end up with 10 as their final value.
 
  • Like
Likes yungman
  • #194
Thanks Mark
Your example is exactly what I have been looking at. Yes, I went through the book, & in this case is NOT address, just a symbol for saying it is a reference variable.

But what I point out in my post is still valid even though my reasoning of( int &) is wrong, it's not passing the address.

Still case A in my program is passing by reference, case B is passing the pointer to pointer.

Thanks
 
  • #195
Jarvis323 said:
Have you learned about references in C++ yet? I don't think a reference in C++ is good to think of as an ADDRESS. In fact it would be much more correct to think of a pointer as an address. Rather, in (A) you are passing a reference (not address) to a pointer. In (B) you are passing a pointer to a pointer (which can be thought of as passing the address of an address).

This might be confusing because it seems you've been calling pointers references up to now (and there is some room for confusion about the difference in C++ anyways). It may also be confusing about the multiple meanings of symbols * and & in different contexts.

https://en.cppreference.com/w/cpp/language/reference

My feeling is in basic agreement with pbuk's post #160. The stuff you're doing now (the way you're using pointers) is more a C style of programming, and generally considered bad practice/style in C++.

Also as pbuk was alluding to, once you learn about classes and object oriented programming, if you start trying to write good code, you'll probably want to use a completely different approach to allocating memory. I usually follow RAII, which is an idiom to follow in order to better organize your use of manually dynamically allocated memory and to avoid making mistakes and causing bugs.

https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization

Anyway, once you understand pointers and references, then you should probably move on because you really have barely scratched the surface of C++, and mostly haven't even seen the ++ parts of C++ yet.

That's just my 2 cents.
Thanks

I thought it's beneficial to learn everything out of each chapter and learn all the possibility. I have no way to predict what's in the future chapters.

I understand where you come from. I feel I have milked the pointers close to the end already and I started looking ahead to the next two chapters. Chapter 11 is on Structure, I read a few pages and I almost felt like kicking myself. I spent a lot of effort in the early chapters to make a nice printout so I have names, tittle, numbers and all nicely, I went through hoops to get multiple arrays to sync together to get the printout that looked nice. That's what the Structure is all about...combining different types of things together in one array or whatever you want to call it!

If I knew that, I would not spend so much time before on this. The problem is where do I draw the line? All I can do is learning one chapter at a time and try to get the max out of it. That's the disadvantage of not going to a class that the professor literally tells you what to study and what not.

thanks
 
  • #196
yungman said:
But what I point out in my post is still valid even though my reasoning of( int &) is wrong, it's not passing the address.
For that you should use double indirection; i.e., a pointer to a pointer to some type.
Here's a simple example:
C++:
#include <iostream>
using std::cout;
using std::cin;
using std::endl;

void passAddr(int **);
int main()
{
    int List[] = { 1, 3, 5, 7, 9 };
    int * ptr = List;                   // Initialize ptr with the address of List, which is itself a kind of pointer.
    
    cout << "Before call to passAddr(), *ptr == " << *ptr << endl;
    passAddr(&ptr);                // Pass the address of the pointer to the first element of the array.
    cout << "After call to passAddr(), *ptr == " << *ptr << endl;
}

void passAddr(int ** pptr)
{
    *pptr += 2;                        // pptr is a pointer to a pointer to an int
}
List is a pointer constant. In essence the type of List is int *.
The 2nd line in main() defines ptr and initializes it to the address that List represents. At this point, ptr contains the address of the first element in the array, 1.
The 4th line calls passAddr(), passing the address of ptr as its parameter.

In the code for passAddr(), we dereference pptr, which gives us access to the address of List, and we increment pptr by 2. The way pointer addition works is that the result is scaled by the type being pointed to (int), which means that we get an address 8 bytes higher (2 * 4 bytes for an int).
After returning to main(), ptr now points to the item at index 2 in the array, namely 5.

Program output:
Code:
Before call to passAddr(), *ptr == 1
After call to passAddr(), *ptr == 5

yungman said:
That's what the Structure is all about...combining different types of things together in one array or whatever you want to call it!
A struct (C and C++ keyword) is not the same as an array. A struct is a user-defined collection of possibly different types. In an array, all of the elements are exactly the same type.
 
  • Like
Likes yungman
  • #198
Mark44 said:
For that you should use double indirection; i.e., a pointer to a pointer to some type.
Here's a simple example:
C++:
#include <iostream>
using std::cout;
using std::cin;
using std::endl;

void passAddr(int **);
int main()
{
    int List[] = { 1, 3, 5, 7, 9 };
    int * ptr = List;                   // Initialize ptr with the address of List, which is itself a kind of pointer.
 
    cout << "Before call to passAddr(), *ptr == " << *ptr << endl;
    passAddr(&ptr);                // Pass the address of the pointer to the first element of the array.
    cout << "After call to passAddr(), *ptr == " << *ptr << endl;
}

void passAddr(int ** pptr)
{
    *pptr += 2;                        // pptr is a pointer to a pointer to an int
}
List is a pointer constant. In essence the type of List is int *.
But List[] is declared as int with initial value only, how can it be pointer constant? I don't get List is a pointer as it's not declared as int*List. I thought there's a difference between ptr where it's declare as int*ptr. I know *ptr = List.
Mark44 said:
The 2nd line in main() defines ptr and initializes it to the address that List represents. At this point, ptr contains the address of the first element in the array, 1.
The 4th line calls passAddr(), passing the address of ptr as its parameter.
This is where I am confused. *ptr=List=&List[0] which is the starting address of List[]. ptr is not equal to &List[0]. passAddr() passing the ADDRESS of ptr in line 4 in main. BUT in the function definition: void passAddr(int**); that means it is passing a pointer to pointer variable ( like int**pptr). But in main, it pass as &ptr, the address of ptr. they are not the same type even thought at the end, it is the same. Can you explain?
Mark44 said:
In the code for passAddr(), we dereference pptr, which gives us access to the address of List, and we increment pptr by 2. The way pointer addition works is that the result is scaled by the type being pointed to (int), which means that we get an address 8 bytes higher (2 * 4 bytes for an int).
After returning to main(), ptr now points to the item at index 2 in the array, namely 5.

Program output:
Code:
Before call to passAddr(), *ptr == 1
After call to passAddr(), *ptr == 5

A struct (C and C++ keyword) is not the same as an array. A struct is a user-defined collection of possibly different types. In an array, all of the elements are exactly the same type.
Actually I prefer to pass pointer as reference ( or pass reference pointer, I still not quite sure) to function. This is more in line with passing any variable as reference to function by declaring void func(int&). It is easier than func(int**).

I have not read Structure, I don't know the naming or anything, just know it can put different types together so I don't have to deal and sync all different arrays together.

Thanks
 
  • #199
jtbell said:
In connection with these threads about learning C++, some of you all might be interested in seeing the book that I taught C++ out of, years ago. I've posted about it just now in the textbooks forum:

https://www.physicsforums.com/threads/old-but-good-c-textbook-available-for-free.992947/
I read the first post in your link, that's kind of the reason I spend extra effort in pointers as you said it's relate to data structure in the advanced class. I also put in extra effort in creating and read/write to files stored on hard disk/flash memory, anything to do with data transport and storage. Actually my book by Gaddis does NOT even go into pointer to pointer or reference pointers. It just declare int func() to return the int pointer. I insisted in learning passing pointer as reference and/or pointer to pointer. It's only two extra days, might be worth my time in the long run...at least that's how I think.

I might be wrong here, there is always a clever or dumb way to write a program. A lot of people put a lot of effort in writing clever lines. I believe as long as I get there, so if my program looks dumb, as long as I am there, who cares! BUT, if I don't know how to manage data, display data, manipulate data, I am done. Dumb programming might cause a few extra lines, but so what in the big picture? Important thing to me is how to make it modular, passing parameters cleanly, clean flow and most important...it works.
 
  • #200
yungman said:
I don't get List is a pointer

List has type "array of int", which the compiler treats as a pointer to the initial item in the array, so it's the same type to the compiler as "pointer to int", so it can be assigned to a variable of that type, such as ptr. The difference is that the address List points to can't be changed--it always points to the first int in the array. Whereas the address that ptr points to can be changed, by assigning some other address to it, as long as that address points to an int. So assigning to ptr a pointer to some element in the array of ints other than the first one is fine.
 
  • Like
Likes yungman
  • #201
yungman said:
I know *ptr = List.

No, it isn't. After the assignment int *ptr = List, the variable ptr points to the first int in the array. So *ptr at that point is not List; it's the first int in the array, which is of type int, not type "array of int", which is the type of List.
 
  • #202
PeterDonis said:
List has type "array of int", which the compiler treats as a pointer to the initial item in the array, so it's the same type to the compiler as "pointer to int",
More precisely, I would say "const pointer to int", because, as you note,
PeterDonis said:
the address List points to can't be changed--it always points to the first int in the array.
 
  • #203
jtbell said:
More precisely, I would say "const pointer to int"

Yes, agreed.
 
  • #204
yungman said:
This is where I am confused. *ptr=List=&List[0] which is the starting address of List[]. ptr is not equal to &List[0].
Yes, you are confused, as well as mistaken. In its declaration ptr is initialized with List, which is the same as &List[0].
The initialization could just as well have been [B]int * ptr = &List[0];[/B], but I chose the shorter form.
yungman said:
passAddr() passing the ADDRESS of ptr in line 4 in main.
A pointer represents an address, so the address of a pointer is a pointer to a pointer to an int, in this case.
yungman said:
BUT in the function definition: void passAddr(int**); that means it is passing a pointer to pointer variable ( like int**pptr). But in main, it pass as &ptr, the address of ptr. they are not the same type even thought at the end, it is the same. Can you explain?
The type of &ptr is pointer to pointer to int.
yungman said:
Actually I prefer to pass pointer as reference ( or pass reference pointer, I still not quite sure) to function. This is more in line with passing any variable as reference to function by declaring void func(int&). It is easier than func(int**).
Like I said before, I've never seen any C++ book with function parameters that mix references and pointers. This should suggest something to you. Sure, you could probably do it, and get something to work, but why? You're mixing together two concepts that really don't belong together, and are obviously confusing to you.
yungman said:
It just declare int func() to return the int pointer.
No. int func() means that func returns an int value, not a pointer.
yungman said:
I insisted in learning passing pointer as reference and/or pointer to pointer.
It's really not a good idea to pass a pointer as a reference parameter. You haven't been able to make it work, so that should be a clue to you. I've shown you an example with double indirection with a parameter of type int**. Before going off into weirdness as you are trying to do, see if you can grasp what my example is doing.
 
  • Like
Likes yungman
  • #205
PeterDonis said:
No, it isn't. After the assignment int *ptr = List, the variable ptr points to the first int in the array. So *ptr at that point is not List; it's the first int in the array, which is of type int, not type "array of int", which is the type of List.
I tried and broke up int *ptr = List to int*ptr;
Mark44 said:
Yes, you are confused, as well as mistaken. In its declaration ptr is initialized with List, which is the same as &List[0].
The initialization could just as well have been [B]int * ptr = &List[0];[/B], but I chose the shorter form.
A pointer represents an address, so the address of a pointer is a pointer to a pointer to an int, in this case.
The type of &ptr is pointer to pointer to int.
Like I said before, I've never seen any C++ book with function parameters that mix references and pointers. This should suggest something to you. Sure, you could probably do it, and get something to work, but why? You're mixing together two concepts that really don't belong together, and are obviously confusing to you.
No. int func() means that func returns an int value, not a pointer.
It's really not a good idea to pass a pointer as a reference parameter. You haven't been able to make it work, so that should be a clue to you. I've shown you an example with double indirection with a parameter of type int**. Before going off into weirdness as you are trying to do, see if you can grasp what my example is doing.

So it's really not advisable to pass pointer as reference pointer, just use function to return the pointer instead as in the book?

the programs that pass pointer as reference seems to work, but they are just funky. I never feel comfortable. It's one thing that it's hard, but if it's not advisable to use at all, then it's no point to pursue anymore.

thanks
 
  • #206
yungman said:
I tried and broke up int *ptr = List to int*ptr;
There's no real difference between this:
C++:
int * ptr;
ptr = List;
and this:
C++:
int * ptr = List;
The first code snippet first declares ptr, and then assigns the address that List represents to it.
The second code snippet declares and initializes ptr to that same address.

The first code snippet is a declaration; the second is a definition.

yungman said:
So it's really not advisable to pass pointer as reference pointer, just use function to return the pointer instead as in the book?
1) It's really not advisable to have a function parameter that is the reference of a pointer.
2) Technically, a void function does not return a value. In the example I posted (post # 196), passAddr() is a void function, so it doesn't "return" anything. If you want a function the modify the value of a pointer, use double indirection; i.e., <type>**, as in that example.

It would be good for you to play with that example, and see what it does using the VS debugger.
 
  • Like
Likes yungman
  • #207
Mark44 said:
There's no real difference between this:
C++:
int * ptr;
ptr = List;
and this:
C++:
int * ptr = List;
The first code snippet first declares ptr, and then assigns the address that List represents to it.
The second code snippet declares and initializes ptr to that same address.

The first code snippet is a declaration; the second is a definition.

1) It's really not advisable to have a function parameter that is the reference of a pointer.
2) Technically, a void function does not return a value. In the example I posted (post # 196), passAddr() is a void function, so it doesn't "return" anything. If you want a function the modify the value of a pointer, use double indirection; i.e., <type>**, as in that example.

It would be good for you to play with that example, and see what it does using the VS debugger.
Another word I have no idea what you mean....indirection.

Honest, my biggest problem learning C++ is the names. I have no idea what the names meant. Also, I don't get use to the symbols, like '&' that really tripped me up. In calculus, physics and electronics, each symbol is chosen to have very specific meaning and they don't use one symbol for totally different meanings ( at least not I can think of this moment). When I see '&', I take it very literal. Until pointers, I really have no issue understanding all the chapters, everything I got tripped are names.

I learned early on int x; &x is the address of x. immediately when I saw void func(int& x) it made sense you pass the address of x as parameter so you can change the value of x in the function. It actually worked for all this time until today you mentioned it.

Like I could have guessed 100 times and I still won't get the meaning of dereferencing. Where did people come up with all these words, it's like C++ has it's only lingo. I hope other languages like Java or Python don't have their own unique lingo, I'd be in trouble learning CS and I might as well give up before I waste too much time.

I might be getting old now compare to before. I studied electronics, RF, electromagnetics, multi-variable calculus, partial differentiations all on my own. I never took classes in any of these, all studied on my own and used in my career. Some are really hard to understand, but I never got tripped up this bad like in C++. About '&' today, it's eye opening. Never even stop and think when it worked so right as address and made sense until today. That's scary. Things look so right and it's so wrong.
 
Last edited:
  • #208
yungman said:
Another word I have no idea what you mean....indirection.
Indirection means using a pointer to get access indirectly, to some memory location. If you have a pointer to a pointer to an int (the type int **), that is double indirection.
yungman said:
Honest, my biggest problem learning C++ is the names. I have no idea what the names meant.
In any field of study, there is some basic terminology that is used. If you don't know what the basic terms mean, you won't get far in that field.
yungman said:
I learned early on int x; &x is the address of x. immediately when I saw void func(int& x) it made sense you pass the address of x as parameter so you can change the value of x in the function.
No, that's not what the parameter declaration int& x means. It is not the address of x: it is a reference to x. A function with this signature, void func2(int * x), is passing the address of x. This is why several people have told you that you aren't understanding the difference between a reference parameter and a pointer parameter.

This goes back to the importance of "learning the names," understanding the meaning of basic terms.

yungman said:
It actually worked for all this time until today you mentioned it.
Except when it didn't work, in several examples of your code that wasn't working.
 
  • Like
Likes yungman
  • #209
ha ha, before today, I looked at pointer of a pointer **ptr as *(*ptr) where it makes sense it's *(...) pointer of (*ptr) pointer. I bet it's dead wrong again!

No, the really hard subjects like electromagnetics, RF and partial differentiation do NOT have confusing symbols and names that I know of after years of studying and working. It's the concept that is so hard to understand, not the English. English wise, it's high school level. You don't get tripped by the words.
 
  • #210
yungman said:
ha ha, before today, I looked at pointer of a pointer **ptr as *(*ptr) where it makes sense it's *(...) pointer of (*ptr) pointer. I bet it's dead wrong again!
**ptr and *(*ptr) mean exactly the same thing, although the name you chose is somewhat confusing.

Here's an example that uses double indirection, with names that are more suggestive of the values they will hold.
C++:
#include <iostream>
using std::cout;
using std::endl;int main()
{
    int val = 23;
    int* pInt = &val;                       // pInt is a pointer to an int
    int** ppInt = &pInt;               // ppInt is a pointer to a pointer to an int
   
    cout << "ppInt == " << ppInt << endl;
    cout << "*ppInt == " << *ppInt << endl;
    cout << "**ppInt == " << **ppInt << endl;
}

Here's the output from one run. Different runs will usually list different addresses.
Code:
ppInt == 012FFB70
*ppInt == 012FFB7C
**ppInt == 23

If I dereference ppInt, I get the address of val. If I dereference ppInt twice, I get the number stored in val. Access via a pointer is called indirection. If you dereference a pointer twice, this is called double indirection.

Here's a graphical representation of the pointers and their relationships. Each box represents one of the variables. In each box are the variable's name (upper left), its address in memory (upper right), and the value stored at the memory location (bottom).

The ? in the ppInt box means that I don't know its address, although it would be easy enough to add a line of code in the program to get it. Notice that the value in the ppInt box is the same as the address in the pInt box, and that the value in the pInt box is the same as the address of val. So ppInt "points to" pInt, and pInt "points to" val.
Pointers.png

BTW, this scheme of representing variables with boxes that contain their names, addresses, and values is something that I came up with independently, early on in teaching C and C++, although I've noticed one or two books that use something similar since then.

Hope this helps.
 
Last edited:
  • Like
Likes yungman

Similar threads

Replies
7
Views
2K
Replies
6
Views
2K
Replies
1
Views
1K
Replies
5
Views
2K
Replies
75
Views
5K
Replies
17
Views
2K
Replies
9
Views
2K
Back
Top