Pages: [1] 2   Go Down
Author Topic: void pointers * something  (Read 1310 times)
0 Members and 1 Guest are viewing this topic.
universe
Offline Offline
Sr. Member
****
Karma: 0
Posts: 258
I'm enjoying my Life
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I am studying about pointer for my arduino project sake, and I found confusion here:
http://www.cplusplus.com/doc/tutorial/pointers/

Code:
#include <iostream>
using namespace std;

void increase (void* data, int psize)
{
  if ( psize == sizeof(char) )
  { char* pchar; pchar=(char*)data; ++(*pchar); }
  else if (psize == sizeof(int) )
  { int* pint; pint=(int*)data; ++(*pint); }
}

int main ()
{
  char a = 'x';
  int b = 1602;
  increase (&a,sizeof(a));
  increase (&b,sizeof(b));
  cout << a << ", " << b << endl;
  return 0;
}

what does it mean pchar=(char*)data; ?
Logged

Offline Offline
Edison Member
*
Karma: 26
Posts: 1339
You do some programming to solve a problem, and some to solve it in a particular language. (CC2)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
what does it mean pchar=(char*)data; ?

(char*)data is an explicit typecast. It temporarily labels data as if it was declared as char* instead of void*. Basically, the compiler won't allow you to assign a void* (pointer to unknown data type) to a char* (pointer to a known data type, a char), because from its point of view, the data at that address (that of a void*) could be anything. You need to tell it you know what you're doing, and force it to treat data as if it pointed to a char.

The fact that nothing can be inferred about what is pointed to by data is made clear by the second argument of increase(), and the way that function is used. The caller tells the function what type data actually points to (well, sort of).
Logged

universe
Offline Offline
Sr. Member
****
Karma: 0
Posts: 258
I'm enjoying my Life
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm trying to digest it,because I also see there is void* data...hmmm

How about this:

Quote
If we write:
*p++ = *q++;
Because ++ has a higher precedence than *, both p and q are increased, but because both increase operators (++) are used as postfix and not prefix, the value assigned to *p is *q before both p and q are increased. And then both are increased. It would be roughly equivalent to:
*p = *q;
++p;
++q;
Like always, I recommend you to use parentheses () in order to avoid unexpected results and to give more legibility to the code.

I dont really get the equivalence between that two..
Could someone help me?
« Last Edit: March 06, 2012, 03:57:56 am by creativen » Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 238
Posts: 24361
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
*p++ = *q++;
Break it down:
1) Fetch what q points to (invisibly call it "temp").
2) Increment q
3) Assign "temp" to what p points to.
4) Increment p

Clearer?
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

universe
Offline Offline
Sr. Member
****
Karma: 0
Posts: 258
I'm enjoying my Life
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

This part is clear for me...
I just think it is not equivalent with this:

*p = *q;
++p;
++q;

here,
1.get the value of q
2. equal it to the value p get
3. the address pointed by p is increased
4. the address pointed by q is increased

if so, it will not give equivalent result as above one.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
void increase (void* data, int psize)
{
  if ( psize == sizeof(char) )
  { char* pchar; pchar=(char*)data; ++(*pchar); }
  else if (psize == sizeof(int) )
  { int* pint; pint=(int*)data; ++(*pint); }
}

Personally I think this is extremely dodgy code. If someone working for me wrote it, I would tell them to try again. Rewrite. For one thing, what if psize happens to be 4 (and this is likely on some machines), and both a float and an int could be 4 bytes. So the function basically is not only incomprehensible, it is doomed to fail.

So I wouldn't bother trying to understand it.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Plus, the indentation sucks.
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 238
Posts: 24361
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
int* pint; pint=(int*)data; ++(*pint);
I really don't understand this style of coding - you've declared a variable, so why not save typing and screen space and initialise it at the same time?
Code:
int* pint=(int*)data;
++(*pint);

Quote
if so, it will not give equivalent result as above one.
I don't understand why you think that.
I think you may be confusing the value of a pointer and the value that it points to.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

In C++ you can just overload the function. eg.


Code:
void increase (int & data)
  {
  data++;
  }

void increase (char & data)
  {
  data++;
  }

void increase (float & data)
  {
  data++;
  }

And so on.

So you need a better example to demonstrate pointers.
Logged

Offline Offline
Edison Member
*
Karma: 26
Posts: 1339
You do some programming to solve a problem, and some to solve it in a particular language. (CC2)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@Nick

I totally agree. I'm sure there are better ways to exemplify pointers...
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks!

In fact you can simplify further with templates:

Code:
template <typename T> void increase (T & data)
  {
  data++;
  }

void setup ()
  {
  float a;
  int b;
  char c;
  long d;
  unsigned long e;
  long long f;

  increase (a);
  increase (b);
  increase (c);
  increase (d);
  increase (e);
  increase (f);
  }
void loop () {}

Now that will handle any (reasonable) type.

Note that this doesn't compile in the IDE (because of the way the preprocessor works). But it will if you move the templated function into a separate .h file, and include that.
Logged

universe
Offline Offline
Sr. Member
****
Karma: 0
Posts: 258
I'm enjoying my Life
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Anw, I am learning the code from here, I am trying to understand so I ask the forum.
http://www.cplusplus.com/doc/tutorial/pointers/
Logged

SF Bay Area (USA)
Offline Offline
Tesla Member
***
Karma: 106
Posts: 6373
Strongly opinionated, but not official!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It's supposed to be demonstrating that a void * pointer can point to data of any type, but it's not a very good example.
malloc() is a better test case (not that a c++ programmer would use malloc(), of course.)
malloc(n) returns a void* pointer to a chunk of n bytes of memory, which you would then cast to whatever type was appropriate:

Code:
int *ip = (int *) malloc(sizeof(int));
char *cp = (char *) malloc(UART_BUFFERSIZE);
paktype *packet = (paktype *) malloc(sizeof(paktype));
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Anw, I am learning the code from here, I am trying to understand so I ask the forum.
http://www.cplusplus.com/doc/tutorial/pointers/

OK, but void pointers are rather esoteric. And thus the examples tend to be confusing. Stick to pointers to real types for now.

By and large you don't need pointers in C++ because you can use references instead. My advice is to keep it simple. Don't waste a lot of time understanding things like void pointers. Just stick to simpler things and get a good grip on them.
Logged

SF Bay Area (USA)
Offline Offline
Tesla Member
***
Karma: 106
Posts: 6373
Strongly opinionated, but not official!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I dunno.  Void* pointers are easy.  They're just an address of some memory.  You can't do much of anything with them (other than pass them around) until you've forcefully identified what's in that memory (with a cast.)   That makes sense, even at machine code levels.

Now, real pointers are harder, because they're supposed to point to a particular type of thing, but that's really just a fiction that is only enforced by the compiler.
Logged

Pages: [1] 2   Go Up
Jump to: