C++ Compare values of double and double* - c++

I have a variable of type double *, which I am initialising to 0 with the line:
double* angle = 0;
I then have a function which takes two variables of type const CCoordinate, and three variables of type double * as parameters. This function takes the values held by the const CCoordinate variables and returns three variables of type double * as returned by calculations performed within the function.
EDIT
The declaration for the function mentioned above is:
int InverseVincenty(const CCoordinate aStartPosition,
const CCoordinate aEndPosition,
double* aDistance,
double* aAngle12,
double* aAngle21);
End Edit
I am now trying to write my own function, which will use this function to calculate the three double * variables, and then perform its own calculation on the double * variables. However, it seems that I am trying to compare the values of doubles with the values of double *, and the compiler is giving me some errors saying that I can't do this...
The kinds of calculation I want to do are things such as:
if((a <= b + 5) || (a >= b -5)){
//do something
}
where a is a double and b is a double*.
The compiler is telling me that it cannot convert from a 'double *' to a 'double', but I'm not trying to convert anything, just trying to compare the values held by both variables... Is this possible at all?
I would have thought that since the pointer is pointing to an address in memory that will hold a value that is of an equivalent data type to the other variable (i.e. double and pointer to a double), that this would be possible?
If not, can anyone suggest another way that I could compare their values?

if((a <= *b + 5) || (a >= *b -5)){
//do something
}
Notice that by doing double* angle = 0;You are not initializing the variable rather its pointer meaning angle will point to 0.
Any attempt to de-reference angle will cause a segmentation fault.
Quoting from your question:
I would have thought that since the pointer is pointing to an address in memory that will hold a value that is of an equivalent data type to the other variable (i.e. double and pointer to a double), that this would be possible?
This is not the case. You correctly say the pointer is pointing to an address in memory that will hold a value that is of an equivalent data type to the other variable. However you need to de-reference the pointer using the * operator to access the values that is pointed.
You might want to look at some introductory guide like: this

b is a pointer so you need to dereference it to get the value.
if((a <= *b + 5) || (a >= *b -5))
You tell us about angle but then never mention it again. The above code requires that b points to a valid memory address.
You can call your functions and retrieve the result as follows.
void test(double *d)
{
*d = 5;
}
double d;
test(&d); // store result in d
Or, using references
void test(double& d)
{
d = 5;
}
double d;
test(d); // store result in d

As with your function signature
int InverseVincenty(const CCoordinate aStartPosition,
const CCoordinate aEndPosition,
double* aDistance,
double* aAngle12,
double* aAngle21);
it looks, that the function will return these three double values via pointer references.
To call the function just provide three double variables
double aDistance;
double aAngle12;
double aAngle21;
and provide their addresses in the function call
InverseVincenty(aStartPosition,aEndPosition,&aDistance,&aAngle12,&aAngle21);
// ^ ^ ^
// Note the address-of operators
afterwards you can go on with your double values as usual.

Related

Error "double** to double*" while passing pointer in a function c/c++

I have a function that takes a double *result. I am aware that pointers need to be passed by reference in a function. When I call the function void ComputeSeriesPointer(double x, int n, double *result); in main with ComputeSeriesPointer(x, n, &result);, I get the error:
cannot convert ‘double**’ to ‘double*’ for argument ‘3’ to ‘void ComputeSeriesPointer(double, int, double*)’
ComputeSeriesPointer(x, n, &result);
^
When working with pointers, aren't they all passed using the & key? The in class examples were all done this way. Even on the internet things were done this way. Any explanation/clarification would be great.
I am also running this with a c++ compiler (as instructed by my professor) because I am using the pow function.
I'm not sure about what you are doing without seeing the complete code, but If you are doing something like this:
void ComputeSeriesPointer(double, int, double*){
// ...
}
int main(){
double *x = ...;
ComputeSeriesPointer(1.0, 1, &x);
// ...
return 0;
}
Then, the problem is the &x. The & operator is used to extract a variable address. In this case, your variable is already a pointer, so writing &x you are getting a "pointer to pointer", in other words, a double**. That's your problem. Call your function in this way: ComputeSeriesPointer(1.0, 1, x)
The function is expecting you to pass the memory address of an actual double variable, not the memory address of a double* pointer variable:
double result; // NOT double*!
ComputeSeriesPointer(x, n, &result);
You can also do this:
double result; // NOT double*!
double *presult = &result;
ComputeSeriesPointer(x, n, presult);
The error message implies that the type of result is already double *. You don't need to use the & operator if the variable is already a pointer of the appropriate type. So you should do
ComputeSeriesPointer(x, n, result);
Either that, or you need to change the declaration of the result variable in the caller from double * to double.
It is likely that you are doing this:
double *myNewResult;
...
ComputeSeriesPointer(x, n, &myNewResult);
By doing this you are passing the address of a double* not double. You dont need double *myNewResult, just double myNewResult. Or if you need myNewResult to be a double* you can just pass it to the function like this:
ComputeSeriesPointer(x, n, myNewResult);
The function is declared like
void ComputeSeriesPointer(double, int, double*);
its third parameter has type double *
But you call the function like
ComputeSeriesPointer(x, n, &result);
where the third argument has type double **
You need to call the function like
ComputeSeriesPointer(x, n, result);
Or change the function declaration and correspondingly its definition such a way that the third parametr had type double **
void ComputeSeriesPointer(double, int, double **);
Passing a pointer into a function is passing by reference; the pointer is the "reference." (C++ muddied waters a little bit by also introducing a "reference" type which pretends it is not a pointer, but that's not relevant to the code example you've given.)
The & operator means "address of." It takes a thing and returns a pointer to that thing. So,
double x = 1; // this is a double
double *pointer_to_x = &x;
double **pointer_to_pointer_to_x = &pointer_to_x;
and so on.
We need to see a little bit more of your code calling ComputeSeriesPointer() to answer properly, but my guess is that you have:
double *result; // this kind of variable stores *the address of* a double-precision number.
ComputeSeriesPointer( x, n, &result );
but you really want:
double result; // this kind of variable stores a double-precision number.
ComputeSeriesPointer( x, n, &result );
so that you are passing in the address that you want ComputeSeriesPointer() to write a result into.

Trying to understand * and & in C++ [duplicate]

This question already has answers here:
What are the differences between a pointer variable and a reference variable?
(44 answers)
Closed 7 years ago.
I have a few questions. This isn't homework. I just want to understand better.
So if I have
int * b = &k;
Then k must be an integer, and b is a pointer to k's position in memory, correct?
What is the underlying "data type" of b? When I output it, it returns things like 0x22fe4c, which I assume is hexadecimal for memory position 2293324, correct?
Where exactly is memory position '2293324'? The "heap"? How can I output the values at, for example, memory positions 0, 1, 2, etc?
If I output *b, this is the same as outputting k directly, because * somehow means the value pointed to by b. But this seems different than the declaration of b, which was declared int * b = k, so if * means "value of" then doesn't mean this "declare b to the value of k? I know it doesn't but I still want to understand exactly what this means language wise.
If I output &b, this is actually returning the address of the pointer itself, and has nothing to do with k, correct?
I can also do int & a = k; which seems to be the same as doing int a = k;. Is it generally not necessary to use & in this way?
1- Yes.
2- There's no "underlying data type". It's a pointer to int. That's its nature. It's as data type as "int" or "char" for c/c++.
3- You shouldn't even try output values of memory which wasn't allocated by you. That's a segmentation fault. You can try by doing b-- (Which makes "b" point to the "int" before it actual position. At least, to what your program thinks it's an int.)
4- * with pointers is an operator. With any data type, it's another data type. It's like the = symbol. It has one meaning when you put == and another when you put =. The symbol doesn't necesarilly correlates with it meaning.
5- &b is the direction of b. It is related to k while b points to k. For example, if you do (**(&b)) you are making the value pointed by the value pointed by the direction of b. Which is k. If you didn't changed it, of course.
6- int & a = k means set the direction of a to the direction of k. a will be, for all means, k. If you do a=1, k will be 1. They will be both references to the same thing.
Open to corrections, of course. That's how I understand it.
In answer to your questions:
Yes, b is a pointer to k: It contains the address of k in the heap, but not the value of k itself.
The "data type" of b is an int: Essentially, this tells us that the address to which b points is the address of an int, but this has nothing to do with b itself: b is just an address to a variable.
Don't try to manually allocate memory to a specific address: Memory is allocated based of the size of the object once initialized, so memory addresses are spaced to leave room for objects to be allocated next to each other in the memory, thus manually changing this is a bad idea.
* In this case is a de-reference to b. As I've said, b is a memory address, but *b is what's at b's address. In this case, it's k, so manipulating *b is the same as manipulating k.
Correct, &b is the address of the pointer, which is distinct from both k and b itself.
Using int & a = k is creating a reference to k, which may be used as if it were k itself. This case is trivial, however, references are ideal for functions which need to alter the value of a variable which lies outside the scope of the function itself.
For instance:
void addThree(int& a) {
a += 3;
}
int main() {
int a = 3; //'a' has a value of 3
addThree(a); //adds three to 'a'
a += 2; //'a' now has a value of 8
return 0;
}
In the above case, addThree takes a reference to a, meaning that the value of int a in main() is manipulated directly by the function.
This would also work with a pointer:
void addThree(int* a) { //Takes a pointer to an integer
*a += 3; //Adds 3 to the int found at the pointer's address
}
int main() {
int a = 3; //'a' has a value of 3
addThree(&a); //Passes the address of 'a' to the addThree function
a += 2; //'a' now has a value of 8
return 0;
}
But not with a copy-constructed argument:
void addThree(int a) {
a += 3; //A new variable 'a' now a has value of 6.
}
int main() {
int a = 3; //'a' has a value of 3
addThree(a); //'a' still has a value of 3: The function won't change it
a += 2; //a now has a value of 5
return 0;
}
There are compliments of each other. * either declares a pointer or dereferences it. & either declares a (lvalue) reference or takes the address of an object or builtin type. So in many cases they work in tandem. To make a pointer of an object you need its address. To use a pointer as a value you dereference it.
3 - If k is a local variable, it's on the stack. If k is a static variable, it's in the data section of the program. The same applies to any variable, including b. A pointer would point to some location in the heap if new, malloc(), calloc(), ... , is used. A pointer would point to the stack if alloca() (or _alloca()) is used (alloca() is similar to using a local variable length array).
Example involving an array:
int array_of_5_integers[5];
int *ptr_to_int;
int (*ptr_to_array_of_5_integers)[5];
ptr_to_int = array_of_5_integers;
ptr_to_array_of_5_integers = &array_of_5_integers;

C++ Comparing Two Integer Values, one simple and one pointer

I have the following function in c++:
bool compareThem(int top_limit, int* maximum)
{
if( top_limit >= maximum )
{
cout << "Error, maximum number shown be greater than top_limit.";
}
}
I want a simple comparison between the integer and integer pointer, though, logically C++ cannot do it, since with == operator, int and int* are not of the same type. How should I then solve it?
Just dereference maximum:
if (top_limit >= *maximum)
// ^
This will compare the int top_limit with the int stored at the memory location pointed to by maximum.
This is one of the fundamentals of C++ and should be covered in your introductory book.
What this code does
bool compareThem(int top_limit, int* maximum)
{
if( top_limit >= maximum )
is comparing top_limit integer value, with address inside maximum pointer variable. To get value of variable to which pointer points, you must dereference pointer variable, which is done with * operator: *maximum.
In C/C++ you can use the * and the & operators to access the value pointed to by an address (pointer) and acquire the address in memory of a value. In your example you try to compare an integer with a pointer, there are a couple of ways I can think of that you might do this (depending on the desired behaviour):
Compare the integer with the value pointed to by the pointer
In order to compare the values of the two objects you need to retrieve the value of the address pointed to by the pointer. To do this you need to use the dereference operator to retrieve the value which you can then treat as an integer, consider the following.
bool myFunction(int a, int* pointer_to_b)
{
int b = *pointer_to_b;
return a > b;
// Or the one line: return a > *pointer_to_b;
}
Compare the address of the pointer to an integer
Since addresses are just integers it is possible to compare a integer to the address stored in a pointer however you should avoid doing this sort of thing unless you really need to. Consider:
bool myBadFunction(int a, int* b)
{
return (int*) a > b;
}
Compare the address of the integer to the address stored in the pointer
I've rarely encountered comparison of an integer to the address of an integer but I have on occasion encountered code comparing the address of a vale to a specific address (but there are usually alternatives and I don't recommend it). For how you might achieve this see the following.
bool myAlmostUselessFunction(int a, int* b)
{
int *address_of_a = &a; //< take the address of a
return address_of_a > b;
}

Where are the pointers supposed to be?

Unfamiliar with C++ programming,
Trying to conceptualize a problem here:
In this exercise we’ll confine ourselves to one numerical type,
float, so we’ll need an array of this type; call it fmemory. However, pointer values
(addresses) are also stored in memory, so we’ll need another array to store them. Since
we’re using array indexes to model addresses, and indexes for all but the largest arrays
can be stored in type int, we’ll create an array of this type (call it pmemory) to hold these
“pointers.”
An index to fmemory (call it fmem_top) points to the next available place where a float
value can be stored. There’s a similar index to pmemory (call it pmem_top). Don’t worry
about running out of “memory.” We’ll assume these arrays are big enough so that each
time we store something we can simply insert it at the next index number in the array.
Other than this, we won’t worry about memory management.
Create a class called Float. We’ll use it to model numbers of type float that are stored
in fmemory instead of real memory. The only instance data in Float is its own “address”;
that is, the index where its float value is stored in fmemory. Call this instance variable
addr. Class Float also needs two member functions. The first is a one-argument constructor
to initialize the Float with a float value. This constructor stores the float
value in the element of fmemory pointed to by fmem_top, and stores the value of
fmem_top in addr. This is similar to how the compiler and linker arrange to store an ordinary
variable in real memory. The second member function is the overloaded & operator.
It simply returns the pointer (really the index, type int) value in addr.
So, what I have deducted was that I need to create something like this
#include <iostream>
using namespace std;
class Float
{
private:
int addr;
float fmem_top,pmem_top;
public:
Float(float* fmem_top){};
Float(int* addr){}
};
int main()
{
//this is where I become confused
}
Would I use something like this in the main method?
Float fmem;
Float pmem;
In this exercise we’ll confine ourselves to one numerical type, float, so we’ll need an array of this type; call it fmemory. However, pointer values (addresses) are also stored in memory, so we’ll need another array to store them. Since we’re using array indexes to model addresses, and indexes for all but the largest arrays can be stored in type int, we’ll create an array of this type (call it pmemory) to hold these “pointers.”
float fmemory[N]; // "we'll need an array of [float]"
int pmemory[N]; // "we'll create an array... pmemory"
An index to fmemory (call it fmem_top) points to the next available place where a float value can be stored. There’s a similar index to pmemory (call it pmem_top). Don’t worry about running out of “memory.” We’ll assume these arrays are big enough so that each time we store something we can simply insert it at the next index number in the array. Other than this, we won’t worry about memory management.
int fmem_top = 0; // "next available place..." fmemory[fmem_top]
int pmem_top = 0; // "similar index to pmemory"
Create a class called Float. We’ll use it to model numbers of type float that are stored in fmemory instead of real memory. The only instance data in Float is its own “address”; that is, the index where its float value is stored in fmemory. Call this instance variable addr.
class Float
{
int addr;
class Float also needs two member functions. The first is a one-argument constructor to initialize the Float with a float value. This constructor stores the float value in the element of fmemory pointed to by fmem_top, and stores the value of fmem_top in addr.
Float(float f)
{
fmemory[fmem_top] = f;
addr = fmem_top;
++fmem_top;
}
This is similar to how the compiler and linker arrange to store an ordinary variable in real memory.
Yeah sure.
The second member function is the overloaded & operator. It simply returns the pointer (really the index, type int) value in addr.
int operator&() { return addr; }
Discussion
There's no indication of the intended use of pmemory, so it's unclear what ought to be done with it. It doesn't make a lot of sense really.
Overall, the interface for Float doesn't provide any clean abstraction for the code using it: the stored values' indices can be retrieved with &, but the caller still needs to know about fmemory to find the actual float value.
I hope the course improves....
Try this. I think the exercise was to abstract for beginners. (I didn't compile this though, it's more for you to understand the concept.)
const int NUM_FLOATS_MAX = 1000;
class Float
{
static float floatArr[];
static int fmem_top;
int addr;
public:
int operator&() { return addr; }
Float(float f) { floatArr[fmem_top] = f; addr = fmem_top; fmem_top++; }
}
// static members need to be defined outside the class declaration
float Float::floatArr[NUM_FLOATS_MAX];
int Float::fmem_top = 0;
// should print 0 and 1, the indices. (How we get the float value
// we don't know -- overload the operator*()?
int main()
{
Float f1 = 1, f2 = 2;
cout << &f1 << endl << &f2 << endl;
}

How to convert double* to a double?

Any ideas for this typecasting problem?
Here's what I am trying to do. This is not the actual code:
LinkedList* angles;
double dblangle;
dblangle = (some function for angle calculation returning double value);
(double*)LinkedListCurrent(angles) = &double;
I hope you get the idea. The last line is causing the problem. Initially angles is void* type so I have to first convert it to double*.
You use the unary * operator to dereference a pointer. Dereferencing a pointer means extracting the value pointed to, to get a value of the original type.
// Create a double value
double foo = 1.0;
// Create a pointer to that value
double *bar = &foo;
// Extract the value from that pointer
double baz = *bar;
edit 2: (deleted edit 1 as it was not relevant to your actual question, but was based on a miscommunication)
From your clarification, it looks like you are wondering how to set a value pointed to by a pointer that has been cast from a void * to a double *. In order to do this, we need to use the unary * on the left hand side of the assignment, in order to indicate that we want to write to the location pointed to by the pointer.
// Get a void * pointing to our double value.
void *vp = &foo;
// Now, set foo by manipulating vp. We need to cast it to a double *, and
// then dereference it using the * operator.
*(double *)vp = 2.0;
// And get the value. Again, we need to cast it, and dereference it.
printf("%F\n", *(double *)vp);
So, I'm assuming that your LinkedListCurrent is returning a void * pointing to some element in the linked list that you would like to update. In that case, you would need to do the following:
*(double*)LinkedListCurrent(angles) = dbangle;
This updated the value pointed to by the pointer returned from LinkedListCurrent to be equal to dbangle. I believe that is what you are trying to do.
If you are trying to update the pointer returned by LinkedListCurrent, you can't do that. The pointer has been copied into a temporary location for returning from the function. If you need to return a pointer that you can update, you would have to return a pointer to a pointer, and update the inner one.
My explanation above is based on what I believe you are trying to do, based on the example snippet you posted and some guesses I've made about the interface. If you want a better explanation, or if one of my assumptions was bad, you might want to try posting some actual code, any error messages you are getting, and a more detailed explanation of what you are trying to do. Showing the interface to the linked list data type would help to provide some context for what your question is about.
edit 3: As pointed out in the comments, you probably shouldn't be casting here anyhow; casts should be used as little as possible. You generally should use templated collection types, so your compiler can actually do typechecking for you. If you need to store heterogenous types in the same structure, they should generally share a superclass and have virtual methods to perform operations on them, and use dynamic_cast if you really need to cast a value to a particular type (as dynamic_cast can check at runtime that the type is correct).
why on earth would you want to use a memory address as a floating point number?
if you meant dereference:
double d = 1.0; // create a double variable with value 1.0
double *dp = &d; // store its address in a pointer
double e = *dp; // copy the value pointed at to another variable
Note this line:
(double*)LinkedListCurrent(angles) = &double;
where you've written &double, it i think should be &dbangle. To improve readability, I would write:
((double*)LinkedListCurrent(angles)) = &dbangle;
However, you should not do this type of conversion as others mentioned.
Use a union. If you want the store two variables in one memory location (but not at the same time), you don't have to pretend that one is the other.
union double_and_ptr {
double d;
double *p;
};
double_and_ptr x, y;
x.d = 0.1;
y.p = &x.d; // store a pointer in the same place as a double
y.d = x.d * 1.2; // store a double in the same place as a ptr
Use reinterpret_cast.
double foo = 3.0;
double* pfoo = &foo;
double bar = reinterpret_cast<double>(pfoo);
In answer to this:
I want to do the opposite of what you have done here. I want to copy the value from the pointer to the d floating point number. How can I do that?
You would do something like this:
// declare a pointer to a double
double *pointer_to_double;
// declare a double
double my_double = 0.0;
// use the indirection operator (*) to dereference the pointer and get the value
// that it's pointing to.
my_double = *pointer_to_double;
This might be done like so in a real program:
void print_chance_of_snow(double *chance)
{
double d = *chance;
d = d * 100; // convert to a percentage
printf("Chance of snow is: %.2f%%\n", d);
}
int main(int argc, char *argv[])
{
double chance_of_snow = 0.45;
print_chance_of_snow(&chance_of_snow);
}