Author Topic: [C] Pointers - what is the point?  (Read 25823 times)

0 Members and 1 Guest are viewing this topic.

Offline andyturk

  • Frequent Contributor
  • **
  • Posts: 895
  • Country: us
Re: [C] Pointers - what is the point?
« Reply #100 on: July 19, 2018, 10:47:23 pm »
One thing I never got a good hand on was the number of days in a month.

That's easy and predictable - unlike seconds in a minute, hours in a day, months in a year, days in a year.

https://youtu.be/-5wpm-gesOY
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6264
  • Country: fi
    • My home page and email address
Re: [C] Pointers - what is the point?
« Reply #101 on: July 19, 2018, 11:24:55 pm »
That's easy and predictable - unlike seconds in a minute, hours in a day, months in a year, days in a year.
Who cares? That is exactly why C has mktime(), localtime(), and gmtime(). Just stuff the datetimes into struct tm structures (at noon if you are only interested in dates, and is_dst=-1 if you don't know if daylight savings time applies), and mktime() will not only normalize the fields but also give you the corresponding time_t: the number of seconds since Jan 1 1970 00:00:00 UTC (not counting any leap seconds; those are accounted for in the broken down struct tm, not in time_t AKA Unix time).

If you are doing any sort of date calculation yourself in hosted C, not using the above functions, you're doing it wrong. (Hosted meaning you have standard C library available.)
« Last Edit: July 20, 2018, 04:00:41 am by Nominal Animal »
 

Offline rhb

  • Super Contributor
  • ***
  • Posts: 3483
  • Country: us
Re: [C] Pointers - what is the point?
« Reply #102 on: July 19, 2018, 11:38:30 pm »
Actually, awk does a good job for dates in the example in the awk book by AWK.
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: [C] Pointers - what is the point?
« Reply #103 on: July 20, 2018, 12:22:56 am »
That's easy and predictable - unlike seconds in a minute, hours in a day, months in a year, days in a year.
Who cares? That is exactly why C has mktime(), localtime(), and gmtime(). Just stuff the datetimes into struct tm structures (at noon if you are only interested in dates, and is_dst=-1 if you don't know if daylight savings time applies), and mktime() will not only normalize the fields but also give you the corresponding time_t: the number of seconds since Jan 1 1970 00:00:00 UTC.

If you are doing any sort of date calculation yourself in hosted C, not using the above functions, you're doing it wrong. (Hosted meaning you have standard C library available.)


"the number of seconds since Jan 1 1970 00:00:00 UTC" - Are you sure of that?

There has been 27 leap seconds since 1970, and time_t doesn't know about any of them.

Code: [Select]
$ date  +"%s  %S"
1532045870  50
$ echo $((1532045870%60))
50

Unless take the time to understand what you are dealing with, you won't understand the assumptions that have been made on your behalf.
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Offline Bassman59

  • Super Contributor
  • ***
  • Posts: 2501
  • Country: us
  • Yes, I do this for a living
Re: [C] Pointers - what is the point?
« Reply #104 on: July 20, 2018, 12:46:47 am »
The classic example for pointers is

I was going to post exactly this example for Simon, but you beat me to it.

but I'll annotate it for him.

Code: [Select]
char* strcpy( char* to, char* from){

   char* ptr;
   ptr = to;

This is subtle. We create the temporary pointer ptr so we don't destroy our to variable.

Code: [Select]
   while( *from ){
The loop continues as long as *from is true. What does that mean?

Remember this is a string copy function. Strings in C are just an array of chars. The convention is that strings are always null-terminated; that is, the last byte in the string is always '\0', which has a numeric value of zero. And also in C, any integer which is zero is considered false, any non-zero value is true.

Now, remember, *from dereferences the pointer from. That is, it returns the value in the location pointed to by from. If the original string whose address is sent to the function (in from) is ABCD\0 then each time through the loop *from will be 'A', then 'B', then 'C', then 'D', then 0 (not the ASCII '0', the value 0). The first four are non-zero, therefore true, and the code in the loop executes and then we go back to the test. When *from is 0, that's false, so the loop exits.

Code: [Select]
      *ptr++ = *from++;
   }

This is classic C. Here's what happens. Note the precedence: the pointer dereference * is done before the post-increment ++.

*from is dereferenced, and you get a character (in example above, 'A', then 'B', etc). That character is put in the memory location pointed to by ptr.

Then the two pointers ptr and from are incremented.

Then the while() case is evaluated again, now using the new thing returned when from is dereferenced.

Code: [Select]
    *ptr = 0;
This null-terminates your destination string. Remember that the code in the loop incremented ptr after the character copy, so it is "looking" at the next place you can put a character. In this case, that next character is the terminator \0 and the string copy is done.

Code: [Select]
   return to;
}

The function has a char* return type, so it returns our result, a pointer to a character. In this case, we know that it is a pointer to the first character in a string. to is passed to us as a pointer to the destination string (assume that space for it exists, this function cannot know if that is true).

Remember at the start when we did the

Code: [Select]
ptr = to? We saved the destination pointer. If we had, instead, incremented to each time through the loop, when we returned it we would have sent the address of the last character in the string -- the null terminator. That's not useful, which is why we copied that address to a temporary and use the temporary for the copy and pointer increment.

This is really the most basic use of pointers, and if you grok this, you'll understand how pointers are generally useful.
« Last Edit: July 20, 2018, 11:31:48 pm by Bassman59 »
 
The following users thanked this post: newbrain

Offline rhb

  • Super Contributor
  • ***
  • Posts: 3483
  • Country: us
Re: [C] Pointers - what is the point?
« Reply #105 on: July 20, 2018, 01:29:10 am »
@Bassman59

Thank you very much for your thorough explication (sorry, English lit major :-).    I just tossed a pebble in the general direction of the answer. You provided a very detailed explanation.  And it really is beautiful.

I get tremendous pleasure out of hearing people who understand in great depth how things work.  Even when I've known it for 20-30 years.  It gives me hope for the human race.

BTW  Do you play bass?  If so acoustic, electric or both?  I play guitar and harmonica.  Almost exclusively an Eastman 810 CE made in 2005.  Best decision I ever made. It completely transformed my playing  after some 30 years.
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6264
  • Country: fi
    • My home page and email address
Re: [C] Pointers - what is the point?
« Reply #106 on: July 20, 2018, 03:59:13 am »
"the number of seconds since Jan 1 1970 00:00:00 UTC" - Are you sure of that?
Okay, I edited it for clarity. It is "the number of seconds since Jan 1 1970 00:00:00 UTC, if leap seconds were not applied" (as explained in the Unix time Wikipedia article).

Leap seconds are taken into calculation when you use one of the three functions I mentioned, in the broken down struct tm members, not in Unix time_t. (In particular, the tm_sec field can be 60, not just 0 to 59.)
« Last Edit: July 20, 2018, 04:03:41 am by Nominal Animal »
 

Offline bsfeechannel

  • Super Contributor
  • ***
  • Posts: 1667
  • Country: 00
Re: [C] Pointers - what is the point?
« Reply #107 on: July 20, 2018, 07:45:29 am »
Quote
I am completely confused, pointers are just another name for some variable, I have read a couple of explanations and I'm still not getting why I would want to use them

In C you don't understand things. You get used to them.

Quote
but if i am pointing at another variable why not just use the variable?

I've seen some books teach that a pointer is just an alias to a variable. Your question shows how this can be misleading.
« Last Edit: July 20, 2018, 07:53:15 am by bsfeechannel »
 

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 19509
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: [C] Pointers - what is the point?
« Reply #108 on: July 20, 2018, 09:43:29 am »
That's easy and predictable - unlike seconds in a minute, hours in a day, months in a year, days in a year.
Who cares? That is exactly why C has mktime(), localtime(), and gmtime(). Just stuff the datetimes into struct tm structures (at noon if you are only interested in dates, and is_dst=-1 if you don't know if daylight savings time applies), and mktime() will not only normalize the fields but also give you the corresponding time_t: the number of seconds since Jan 1 1970 00:00:00 UTC (not counting any leap seconds; those are accounted for in the broken down struct tm, not in time_t AKA Unix time).

If you are doing any sort of date calculation yourself in hosted C, not using the above functions, you're doing it wrong. (Hosted meaning you have standard C library available.)

The latter is precisely the point I have had to make to implementors on more than one occasion :(

But your first paragraph is wrong; unix time doesn't take account of leap seconds.

Leap seconds cause serious problems in distributed systems that rely on timestamps, e.g. telecom, or high reliability distributed file systems.

As a result there have been serious attempts to redefine time in such a was as to avoid leap seconds.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline bd139

  • Super Contributor
  • ***
  • Posts: 23024
  • Country: gb
Re: [C] Pointers - what is the point?
« Reply #109 on: July 20, 2018, 09:47:10 am »
 

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 19509
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: [C] Pointers - what is the point?
« Reply #110 on: July 20, 2018, 10:07:01 am »
I've seen some books teach that a pointer is just an alias to a variable. Your question shows how this can be misleading.

I rather like the Algol68 nomenclature....

An int is just that, no more, e.g. 59 is an int and unsurprisingly it cannot change during execution. In other words it is what most languages term a constant.

A ref int refers to an int, and can change during execution. In other words it is what most languages term a variable of type int.

A ref ref int refers to a ref int. In C this would be a pointer to an int.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline bd139

  • Super Contributor
  • ***
  • Posts: 23024
  • Country: gb
Re: [C] Pointers - what is the point?
« Reply #111 on: July 20, 2018, 10:32:05 am »
Algol 68, much as many things it did, gets it right there. Also considers immutability explicitly up front.

I think the killer for pointers in C is sometimes the syntax used. Dereferencing a pointer to an int and incrementing it for example. Yuck. But it works.
 

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 19509
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: [C] Pointers - what is the point?
« Reply #112 on: July 20, 2018, 10:39:30 am »
Algol 68, much as many things it did, gets it right there. Also considers immutability explicitly up front.

The standard lament is that Algol68 is an improvement on most of its successors.

But it was too complex for the machines and compiler technology of the day (and random i/o devices lacking lowercase and punctuation characters). Hence the many subsets of the language.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 9951
  • Country: nz
Re: [C] Pointers - what is the point?
« Reply #113 on: July 20, 2018, 11:00:41 am »
Don't think of pointers as something that solves a problem, then try to figure out what that problem is and how it needs pointers. This kind of thinking is wrong and will confuse you.

Unless you're making your own OS you can get by without using any pointers.
It's just that pointers make some things sooo much easier and faster and more elegant than doing the same thing without using pointers.

Its like when you first learned about Arrays and how to use them, it opens up a word of possibilities.
Sure, you could write code without using arrays but damn would it be ugly.

One example where i used pointers recently was when writing data to a large RGB led display.
I had an array storing the color of all the pixels.  Timer interrupt code was reading the array and drawing the data on the LED pixels.
Some other code was updating the array with new text/images.
Now the problem is that sometimes it would be in the middle of adding an image to the array and the LED display would get updated when it was half drawn.

The solution for this is to double buffer it, have one array you only use for adding content and one array you only use for updating the LED display.  Then you can swap them around using pointers after you finish adding content.
A couple of pointers works well for this, you can have two pointers pDrawingImageBuffer and pActiveImageBuffer and quickly swap what array they actually point to.

This means your code that is updating the LED display can work with only one pointer and your code for drawing text/images can work only with the other pointer.
You can quickly swap what they point to around and none of those code blocks know any different.
« Last Edit: July 20, 2018, 11:15:21 am by Psi »
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline rhb

  • Super Contributor
  • ***
  • Posts: 3483
  • Country: us
Re: [C] Pointers - what is the point?
« Reply #114 on: July 20, 2018, 11:38:37 am »
Algol 68, much as many things it did, gets it right there. Also considers immutability explicitly up front.

The standard lament is that Algol68 is an improvement on most of its successors.

That should read Algol 60, not 68.  Algol 68 suffered from massive feature creep.

FWIW History is important here.  The predecessor to C, B, is available again on Unix V0 using a PDP-7 emulator.  So you can see first hand how Ken and Dennis were struggling to make system development easier.  They had worked on Multics for some time, so they were very familiar with the problem.

https://github.com/DoctorWkt/pdp7-unix

https://www.bell-labs.com/usr/dmr/www/bintro.html
« Last Edit: July 20, 2018, 11:53:04 am by rhb »
 

Offline bd139

  • Super Contributor
  • ***
  • Posts: 23024
  • Country: gb
Re: [C] Pointers - what is the point?
« Reply #115 on: July 20, 2018, 11:43:44 am »
This one always sticks in my head with Algol: http://cowlark.com/2009-11-15-go/
 
The following users thanked this post: newbrain

Offline brucehoult

  • Super Contributor
  • ***
  • Posts: 4037
  • Country: nz
Re: [C] Pointers - what is the point?
« Reply #116 on: July 20, 2018, 01:32:06 pm »
One example where i used pointers recently was when writing data to a large RGB led display.
I had an array storing the color of all the pixels.  Timer interrupt code was reading the array and drawing the data on the LED pixels.
Some other code was updating the array with new text/images.
Now the problem is that sometimes it would be in the middle of adding an image to the array and the LED display would get updated when it was half drawn.

The solution for this is to double buffer it, have one array you only use for adding content and one array you only use for updating the LED display.  Then you can swap them around using pointers after you finish adding content.
A couple of pointers works well for this, you can have two pointers pDrawingImageBuffer and pActiveImageBuffer and quickly swap what array they actually point to.

This means your code that is updating the LED display can work with only one pointer and your code for drawing text/images can work only with the other pointer.
You can quickly swap what they point to around and none of those code blocks know any different.

You could just as well make pDrawingImageBuffer and pActiveImageBuffer integers with value 0 or 1, and make your array:

RGB pixels[2][NPIXELS]

Anything you can do with pointers you can do with array indexes instead. Once the optimiser gets done with it the machine code will be virtually identical.
 

Offline bd139

  • Super Contributor
  • ***
  • Posts: 23024
  • Country: gb
Re: [C] Pointers - what is the point?
« Reply #117 on: July 20, 2018, 01:42:54 pm »
How do you implement a dynamic sized ring buffer with arrays?
 

Offline sokoloff

  • Super Contributor
  • ***
  • Posts: 1799
  • Country: us
Re: [C] Pointers - what is the point?
« Reply #118 on: July 20, 2018, 02:17:46 pm »
Anything you can do with pointers you can do with array indexes instead. Once the optimiser gets done with it the machine code will be virtually identical.
Call malloc.
Write a function that calls a user-specified function.
 

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3146
  • Country: ca
Re: [C] Pointers - what is the point?
« Reply #119 on: July 20, 2018, 02:18:41 pm »
Anything you can do with pointers you can do with array indexes instead.

Of course. But it will be very tedious if your elements are of variable length.

Once the optimiser gets done with it the machine code will be virtually identical.

I wouldn't agree with that. To access an element of the array, the CPU must calculate the address of the element. It must multiply the index by the size of the element and add an offset. If you have a pointer, the calculation is not needed.

This may not be a problem if the CPU has scaled indexed addressing (e.g. [RAX*8 + offset] in i86), but if the element size is bigger or not a power of two, or CPU doesn't have adequate addressing modes, there may be substantial overhead.

If you try to implement linked lists through array indexes instead of pointers, the overhead of walking the list may be very substantial.

 

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 19509
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: [C] Pointers - what is the point?
« Reply #120 on: July 20, 2018, 02:32:57 pm »
Anything you can do with pointers you can do with array indexes instead. Once the optimiser gets done with it the machine code will be virtually identical.

Only if every element is the same size and is known at compile time. Frequently neither of those conditions is true.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline Tepe

  • Frequent Contributor
  • **
  • Posts: 572
  • Country: dk
Re: [C] Pointers - what is the point?
« Reply #121 on: July 20, 2018, 02:41:31 pm »
For example, if you write a[ i ] to access the i'th element of a, this is exactly the same as writing *(a+i)
A fun effect of a[ i ] being syntactic sugar for *(a + i) is that because *(a + i) is the same as *(i + a) due to addition being commutative,  i[ a ] is the same as a[ i ].


Edit: An example
Code: [Select]
#include <stdio.h>

int main(void)
{
    char a[5];

    2[a] = 'a';
    printf("%c\n", a[2]);
    return 0;
}
« Last Edit: July 20, 2018, 02:56:51 pm by Tepe »
 

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3146
  • Country: ca
Re: [C] Pointers - what is the point?
« Reply #122 on: July 20, 2018, 03:23:29 pm »
An example

Code: [Select]
#include <stdio.h>

int tepe_sum(int a, int b) {
  return &((void*)a)[b];
}

int main(void)
{
  printf("2 + 2 = %d\n",tepe_sum(2,2));
}
 

Offline T3sl4co1l

  • Super Contributor
  • ***
  • Posts: 21686
  • Country: us
  • Expert, Analog Electronics, PCB Layout, EMC
    • Seven Transistor Labs
Re: [C] Pointers - what is the point?
« Reply #123 on: July 20, 2018, 04:18:25 pm »
You could just as well make pDrawingImageBuffer and pActiveImageBuffer integers with value 0 or 1, and make your array:

RGB pixels[2][NPIXELS]

Anything you can do with pointers you can do with array indexes instead. Once the optimiser gets done with it the machine code will be virtually identical.

Not quite -- the elements of pixels[a] are themselves arrays; that is, pixels is a pointer to an array of pointers to data!

Nested arrays are almost syntactic sugar, easily forgotten -- but one should always use array[x + y*WIDTH] when they mean it, and use nested arrays for other things.

It could be that, if link-time optimization is allowed, such that the as-written semantics no longer apply exactly -- a multidimensional array could be collapsed into a single one (even better, collapsed into a convenient width, if every last clock cycle is required, and possible additional memory usage is acceptable?).  I don't think this is within the realm of normal optimization though.

Hmm, I don't have a direct example for where nested arrays would be useful.  Dynamic arrays perhaps, like if you're doing a text editor as an array of strings?  You need some way to track the individual array lengths, of course (whether by null-terminated bytes, or an array of lengths).

Tim
Seven Transistor Labs, LLC
Electronic design, from concept to prototype.
Bringing a project to life?  Send me a message!
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6264
  • Country: fi
    • My home page and email address
Re: [C] Pointers - what is the point?
« Reply #124 on: July 20, 2018, 04:21:47 pm »
Leap seconds cause serious problems in distributed systems that rely on timestamps, e.g. telecom, or high reliability distributed file systems.
Very true.

Linux kernels nowadays do support CLOCK_TAI. POSIX.1 clock_gettime(CLOCK_REALTIME, &timespec) reports the Unix time (similar to time(), but at a nanosecond resolution), which does NOT take leap seconds into account. However, clock_gettime(CLOCK_TAI, &timespec) reports the number of seconds since Epoch, including leap seconds, if the userspace is configured to handle leap seconds correctly.

(Basically, ntpd or whatever takes care of clock sync, needs to do an adjtimex() call, with .modes=ADJ_TAI and .constant=leapsecs where leapsecs is the number of leap seconds since 1970-01-01. When a leap second occurs, an adjtimex() call with .modes=ADJ_OFFSET|ADJ_TAI, .offset-=1000, .constant+=1 atomically steps back the Unix time by one second (simulating the extra second inserted), while incrementing the number of leap seconds, so that CLOCK_TAI stays monotonic. It can be done at any point during the leap second.)

Just for fun, I set the TAI offset to 27 by hand, so right now on my laptop, CLOCK_REALTIME = 1532102354.146984744 but CLOCK_TAI =  1532102381.146988316 (indicating 27 leap seconds since 1970-01-01). The difference in the fractional part is only due to the two clocks not being read simultaneously.  So, at least Linux does have the necessary kernel support; only the userspace part is lagging.

The only reason why time(), mktime(), localtime(), or gmtime() cannot be switched to CLOCK_TAI is that it might break backwards compatibility. Otherwise, it would be a very simple change to canonically handle even leap seconds correctly, with a time_t that did include leap seconds.

In practice, the leap second is addressed by ntp daemons by adjusting the clock rate; slewing. It usually takes about two or three days for the compensation cycle to be over, and during this time, the clock sync across machines tends to slip a bit more than usual.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf