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

0 Members and 1 Guest are viewing this topic.

Offline IonizedGears

  • Regular Contributor
  • *
  • Posts: 248
  • Country: us
Re: [C] Pointers - what is the point?
« Reply #25 on: July 16, 2018, 09:31:47 pm »
A few notes for especially important for Embedded systems and other resource-limited environments:

Dereferencing pointers to access the memory that's being pointed to takes more time than directly using the variable.

Pointer size is usually dependent on the architecture of the system. Very important when pointers are 16 bits wide on an 8 bit architecture.

Accessing struct members takes time and having to dereference a struct first takes even more time on top of that.


Knowing these things is important if you're pinching cycles which has given me this rule of thumb:

Limit dereferencing as much as you can and especially limit it in the case of loops. You will have to optimize memory usage vs. time and it isn't as clear cut as one would like it to be.

Do not limit dereferencing to the point of seriously hurting readability unless you heavily document what is being done and why it was done that way. This one is a general rule of thumb but still very important.

IX
« Last Edit: July 16, 2018, 09:51:18 pm by IonizedGears »
I am an EE with interests in Embedded, RF, Control Systems, and Nanotech.
 

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6242
  • Country: fi
    • My home page and email address
Re: [C] Pointers - what is the point?
« Reply #26 on: July 16, 2018, 10:40:44 pm »
A lot of computational physicists with Fortran background ask the same question.  (There is a lot of physics code in F95, because it is easier to write efficient math/simulation code in Fortran for current processors, than it is to do the same in C.  Vectorization (using SSE2/AVX/AVX2/AVX512 in particular) is much easier for the Fortran compiler than it is to C compiler.

The first time you'll find the true utility of pointers is when you need runtime polymorphism (some variant of subtyping) in your data.

Think of a stack, that can contain different types of items, of varying sizes.  You could use an array of unions that can hold each type of item you want. But you could also make it a linked list of different structures. For example:
Code: [Select]
#include <stdlib.h>
#include <string.h>

enum {
    STACK_STRING = 0,
    STACK_INT,
    STACK_FLOAT
};

typedef  union stack_all   stack_all;

typedef  struct stack_any  stack_any;
struct stack_any {
    stack_any *next;
    char       type;
};

typedef struct {
    stack_any *next;
    char       type;  /* = STACK_STRING */
    char       value[];
} stack_string;

typedef struct {
    stack_any *next;
    char       type;  /* = STACK_INT */
    int        value;
} stack_int;

typedef struct {
    stack_any *next;
    char       type;  /* = STACK_FLOAT */
    float      value;
} stack_float;

union stack_all {
    stack_any    any;
    stack_string s;
    stack_int    i;
    stack_float  f;
};

static stack_any *stack = NULL;

static inline stack_any *pop(void)
{
    stack_any *item;

    if (!stack)
        return NULL;

    item = stack;
    stack = item->next;
    item->next = NULL;

    return item;
}

static inline void push(stack_any *item)
{
    item->next = stack;
    stack = item;
}

static inline int push_string(const char *s)
{
    const size_t  slen = (s) ? strlen(s) : 0;
    stack_string *item;

    item = malloc(slen + 1 + sizeof (stack_string));
    if (!item)
        return -1;

    item->next = stack;
    item->type = STACK_STRING;
    if (slen > 0)
        memcpy(item->value, s, slen);
    item->value[slen] = '\0';

    stack = (stack_any *)item;

    return 0;
}

static inline int push_int(int i)
{
    stack_int *item;

    item = malloc(sizeof *item);
    if (!item)
        return -1;

    item->next = stack;
    item->type = STACK_INT;
    item->value = i;

    stack = (stack_any *)item;

    return 0;
}

static inline int push_float(float f)
{
    stack_float *item;

    item = malloc(sizeof *item);
    if (!item)
        return -1;

    item->next = stack;
    item->type = STACK_FLOAT;
    item->value = f;

    stack = (stack_any *)item;

    return 0;
}
Now, the reason the stack = (stack_any *)item; lines are valid, and casting between any stack_ types is allowed, is twofold: First, all those types need to have the same common initial members. For a stack implemented via a linked list, that means the pointer to the next (older) item in the stack, and the type of the current item in the stack.  Second, the compiler needs to have union stack_all visible. It is an union of all those structure types with the same common initial members.  (A lot of C programmers are not aware that the visibility of the union type suffices; it is not necessary to use the union type at all. Simply having the union type visible, and the types having the same common initial members, due to C99 6.5.2.3p5, means you can cast a structure of any of those types to another of those types, and examine the common initial members. Cast to the correct type (used when assigning the fields) is needed to access the type-specific fields.)

(A similar (but older, pre-C99) mechanism was used in POSIX.1 and its predecessors (SVRv4, 4.4BSD) to describe socket addresses (struct sockaddr).  C99 standardized a way to implement those in a backwards compatible manner via this union mechanism; however, because of such a large body of existing code relying the same operation without having such an union visible, most C compilers do not actually need to have that union visible.)

In microcontrollers, you can sometimes see similar queues or stacks used, when commands/requests and results are processed asynchronously, and more than one can be "in flight" at the same time.
 

Offline IonizedGears

  • Regular Contributor
  • *
  • Posts: 248
  • Country: us
Re: [C] Pointers - what is the point?
« Reply #27 on: July 16, 2018, 10:50:17 pm »
A lot of computational physicists with Fortran background ask the same question.  (There is a lot of physics code in F95, because it is easier to write efficient math/simulation code in Fortran for current processors, than it is to do the same in C.  Vectorization (using SSE2/AVX/AVX2/AVX512 in particular) is much easier for the Fortran compiler than it is to C compiler.

The first time you'll find the true utility of pointers is when you need runtime polymorphism (some variant of subtyping) in your data.

Think of a stack, that can contain different types of items, of varying sizes.  You could use an array of unions that can hold each type of item you want. But you could also make it a linked list of different structures. For example:
Code: [Select]
#include <stdlib.h>
#include <string.h>

enum {
    STACK_STRING = 0,
    STACK_INT,
    STACK_FLOAT
};

typedef  union stack_all   stack_all;

typedef  struct stack_any  stack_any;
struct stack_any {
    stack_any *next;
    char       type;
};

typedef struct {
    stack_any *next;
    char       type;  /* = STACK_STRING */
    char       value[];
} stack_string;

typedef struct {
    stack_any *next;
    char       type;  /* = STACK_INT */
    int        value;
} stack_int;

typedef struct {
    stack_any *next;
    char       type;  /* = STACK_FLOAT */
    float      value;
} stack_float;

union stack_all {
    stack_any    any;
    stack_string s;
    stack_int    i;
    stack_float  f;
};

static stack_any *stack = NULL;

static inline stack_any *pop(void)
{
    stack_any *item;

    if (!stack)
        return NULL;

    item = stack;
    stack = item->next;
    item->next = NULL;

    return item;
}

static inline void push(stack_any *item)
{
    item->next = stack;
    stack = item;
}

static inline int push_string(const char *s)
{
    const size_t  slen = (s) ? strlen(s) : 0;
    stack_string *item;

    item = malloc(slen + 1 + sizeof (stack_string));
    if (!item)
        return -1;

    item->next = stack;
    item->type = STACK_STRING;
    if (slen > 0)
        memcpy(item->value, s, slen);
    item->value[slen] = '\0';

    stack = (stack_any *)item;

    return 0;
}

static inline int push_int(int i)
{
    stack_int *item;

    item = malloc(sizeof *item);
    if (!item)
        return -1;

    item->next = stack;
    item->type = STACK_INT;
    item->value = i;

    stack = (stack_any *)item;

    return 0;
}

static inline int push_float(float f)
{
    stack_float *item;

    item = malloc(sizeof *item);
    if (!item)
        return -1;

    item->next = stack;
    item->type = STACK_FLOAT;
    item->value = f;

    stack = (stack_any *)item;

    return 0;
}
Now, the reason the stack = (stack_any *)item; lines are valid, and casting between any stack_ types is allowed, is twofold: First, all those types need to have the same common initial members. For a stack implemented via a linked list, that means the pointer to the next (older) item in the stack, and the type of the current item in the stack.  Second, the compiler needs to have union stack_all visible. It is an union of all those structure types with the same common initial members.  (A lot of C programmers are not aware that the visibility of the union type suffices; it is not necessary to use the union type at all. Simply having the union type visible, and the types having the same common initial members, due to C99 6.5.2.3p5, means you can cast a structure of any of those types to another of those types, and examine the common initial members. Cast to the correct type (used when assigning the fields) is needed to access the type-specific fields.)

(A similar (but older, pre-C99) mechanism was used in POSIX.1 and its predecessors (SVRv4, 4.4BSD) to describe socket addresses (struct sockaddr).  C99 standardized a way to implement those in a backwards compatible manner via this union mechanism; however, because of such a large body of existing code relying the same operation without having such an union visible, most C compilers do not actually need to have that union visible.)

In microcontrollers, you can sometimes see similar queues or stacks used, when commands/requests and results are processed asynchronously, and more than one can be "in flight" at the same time.
Pretty neat but 8 bit microcontrollers, at least those from Microchip, don't have malloc due to the issues it could cause in a limited environment. There are ways of implementing the same design patterns without malloc and if you really wanted you could easily implement a pseudo-malloc if you really wanted.

I believe most 16 and 32 bitters support malloc, though.

IX
« Last Edit: July 16, 2018, 11:03:34 pm by IonizedGears »
I am an EE with interests in Embedded, RF, Control Systems, and Nanotech.
 

Offline emece67

  • Frequent Contributor
  • **
  • !
  • Posts: 614
  • Country: 00
Re: [C] Pointers - what is the point?
« Reply #28 on: July 16, 2018, 10:55:13 pm »
.
« Last Edit: August 19, 2022, 01:54:31 pm by emece67 »
 

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26896
  • Country: nl
    • NCT Developments
Re: [C] Pointers - what is the point?
« Reply #29 on: July 16, 2018, 10:59:07 pm »
Meanwhile I'd like to suggest to Simon to buy a good book about programming C for microcontrollers. Judging by his other questions he is using mostly 8 bit controllers and on those pointers are better to be avoided anyway because they are slow. On a typical 8 bit microcontroller it is faster to use global variables (*). In general it is good to avoid pointers because they offer a myriad of ways to shoot yourself in your feet and problems are hard to debug. Range checking when accessing arrays is highly recommended.

IMHO the way array variables are automatically pointers in C isn't very consequent. After all a 'regular' variable could be seen as an array with only one element. This tends to confuse people because you see things like this:
Code: [Select]
int a;
int b[2];
memset(&a, 0, sizeof(a));
memset(b, 0, sizeof(b));

* On 16 and 32 bit platforms pointers are much faster because (usually) the memory layout and/or instruction set are better suited to use pointers.
« Last Edit: July 16, 2018, 11:03:04 pm by nctnico »
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline Wilksey

  • Super Contributor
  • ***
  • Posts: 1329
Re: [C] Pointers - what is the point?
« Reply #30 on: July 16, 2018, 11:35:03 pm »
Simply because why pass by value, create multiple blocks of memory to store the same data when you can pass by reference (pointer) to address the variable by memory location.

If I had a 2048 byte array or even 1024 byte array of data and I didn't use pointers i'd soon run out of memory to copy the data into.

A pointer points to the first element of that array or data structure and you can do the rest, make sure you abide by boundary.

Function pointers are useful also.
 

Offline brucehoult

  • Super Contributor
  • ***
  • Posts: 4028
  • Country: nz
Re: [C] Pointers - what is the point?
« Reply #31 on: July 16, 2018, 11:37:38 pm »
I've only just specified my first array, it was an easy way of having multiple locations to store values in from each ADC channel and be able to move from channel to channel by incrementing the variable used as an index.

Actually, in C arrays and pointers are two sides of the same coin.

For example, if you write a[ i ] to access the i'th element of a, this is exactly the same as writing *(a+i)

What many people don't realise is it's also the same as  i[a]

BCPL wrote it as  a!i (or  i!a) which is closer to the truth but looks less like math.
 

Offline sleemanj

  • Super Contributor
  • ***
  • Posts: 3024
  • Country: nz
  • Professional tightwad.
    • The electronics hobby components I sell.
Re: [C] Pointers - what is the point?
« Reply #32 on: July 17, 2018, 12:17:07 am »
* Dynamic memory allocation (reallocation)
* Linked lists, you can't do linked lists without a pointer (and dynamic memory allocation), circular buffers, FIFO stacks.... all need pointers to be efficient
* Pass by reference (although C++ & references are simpler here if you can do that)
* In C, strings, you really can't do strings without pointers, char * , or as mentioned char [] is virtually just a pointer
* Function pointers and jump tables
* Machine registers, those are all effectively pointers in C (eg in AVR land, volatile uint8_t *)
* In the AVR world, PROGMEM and EEMEM


« Last Edit: July 17, 2018, 12:18:53 am by sleemanj »
~~~
EEVBlog Members - get yourself 10% discount off all my electronic components for sale just use the Buy Direct links and use Coupon Code "eevblog" during checkout.  Shipping from New Zealand, international orders welcome :-)
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: [C] Pointers - what is the point?
« Reply #33 on: July 17, 2018, 12:40:12 am »
Pointers have many levels of understanding - and you can't get them all in one go, you need to build up level by level.

The first conceptual model for pointers is it is a nice "handle" to where some data is held. You can either use the data directly, or indirectly through the pointer (using the '*' operator). You can get the handle of any given bit of data with the '&' operator.

As C functions only return one value, and C functions are "pass by value" pointers are used to give functions the ability to update data that is outside of the function's scope.

Code: [Select]

int swap( int *a, int *b)
{
  int temp;
  temp = *a; // Save the value of 'a' in 'temp'
  *a = *b;     // Move 'b' into 'a'
  *b = temp; // update 'b' with the saved value in 'temp'.
}
...
   if(b < a)   // Put the lowest value in 'a'
     swap(&a, &b);
...

The next level is that the pointers are a handle to the first of a series of data - and you can do math on the pointer to access other items in the series.

Code: [Select]

int string_length(char *string) {
  int len = 0;
  while(*string != '\0') {
    len = len + 1;       // Could use the ++ operator too...
    string = string+1; // Move on to the next item
  }
  return len;
}
...
   char string[] = "My string";

   printf("String '%s' is %i characters long, excluding the terminating NULL\n",
            string, string_length(string));
...

The next level after that is that pointers can be the location of a structure holding multiple items, accessed using the "->" operator:

Code: [Select]
   struct Person {
      char name[100];
      unsigned age;
   };
   struct Person alice = {"Alice", 22};
   struct Person bob = {"Bob", 19};
....
   struct Person *person_ptr;
   person_ptr = &bob;  // Get the pointer to 'bob' in memory
...
   printf("%s is %i years old\n", person_ptr->name, person_ptr->age); // Print the person's details
...

The "glowing brain" level is when you use dynamic memory allocation to grab more memory at run time, allowing you to create and destroy structures like linked lists and trees, and process work with data where you don't know the size at compile time. The thing that does your head in about this is that the data structures used contain pointers that point to the data structure being defined:

Code: [Select]
struct ListItem {
   struct ListItem *next;  /* Address of next item in list */
   int value1;
   int value2;
}

Code to use this sort of thing becomes a familiar pattern:

Code: [Select]
struct ListItem *first_item;

int add_item_to_list(int value1, int value2) {
   struct ListItem *new_item;

   /* Allocate some memory */
   new_item = malloc(sizeof(struct ListItem));

   /* Detect if we were out of memory */
   if(new_item == NULL) 
     return 0;  /* Failed - out of memory */

   /* Clear out the entire block of memory */
   memset(new_item,0,sizeof(struct ListItem));

   /* Set the values in the item */
   new_item->value1 = value1;
   new_item->value2 = value2;
 
   /* Add to the linked list at the front */
   new_item->next = first_item;
   first_item = new_item;

   /* Successfully added item to the front of the list */
   return 1;
}

And somewhere off to the side is function pointers - these are pointer that hold the location of code and are used as callback functions, signal handlers and interrupt handling.

PS. Code most likely has many errors - was just typed in on the fly.
« Last Edit: July 17, 2018, 12:42:01 am by hamster_nz »
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 brucehoult

  • Super Contributor
  • ***
  • Posts: 4028
  • Country: nz
Re: [C] Pointers - what is the point?
« Reply #34 on: July 17, 2018, 12:41:27 am »
Pretty neat but 8 bit microcontrollers, at least those from Microchip, don't have malloc due to the issues it could cause in a limited environment. There are ways of implementing the same design patterns without malloc and if you really wanted you could easily implement a pseudo-malloc if you really wanted.

I believe most 16 and 32 bitters support malloc, though.

Saying that a processor supports (or doesn't support) malloc is pretty much nonsense. Malloc is just a function that manages a (hopefully large) array of bytes, chopping it up as requested, and keeping track of which parts are used and which parts are not.

What a processor might or might not support is "indirect addressing". If you've got indirect addressing (or the ability to run code from RAM, and modify it at runtime) then the programmer (or their library writer) can implement malloc.

If you don't have indirect addressing then you can't even have *arrays*.

Many early computers didn't have any form of indirect addressing. When the programmer wanted to work with an array or pointer they would modify the appropriate load or store instruction just before executing it. Pretty soon index registers were invented. This let you calculate a value into the index register and then have it added to the absolute address contained in the load or store instruction. Often the index register would be smaller than the full address size, making it not useful as a general pointer. This happened as recently as the 6502.

Fortunately, as they don't have program memory you can modify on the fly, even the smallest PIC10s support indirect addressing via the FSR and IND registers. Malloc wouldn't be very useful on them, since you only have 32 bytes of memory, but you could write it if you wanted.
 

Offline sleemanj

  • Super Contributor
  • ***
  • Posts: 3024
  • Country: nz
  • Professional tightwad.
    • The electronics hobby components I sell.
Re: [C] Pointers - what is the point?
« Reply #35 on: July 17, 2018, 12:47:31 am »
Pretty neat but 8 bit microcontrollers, at least those from Microchip,

malloc etc works just fine with AVR libc

https://www.microchip.com/webdoc/AVRLibcReferenceManual/group__avr__stdlib_1ga4996af830ebe744d9678e5251dfd3ebd.html

Of course, dynamic allocation is to be avoided in low memory environments, but if you need to, go for it, carefully.
~~~
EEVBlog Members - get yourself 10% discount off all my electronic components for sale just use the Buy Direct links and use Coupon Code "eevblog" during checkout.  Shipping from New Zealand, international orders welcome :-)
 

Online ajb

  • Super Contributor
  • ***
  • Posts: 2601
  • Country: us
Re: [C] Pointers - what is the point?
« Reply #36 on: July 17, 2018, 01:06:04 am »
* Machine registers, those are all effectively pointers in C (eg in AVR land, volatile uint8_t *)
I'm not sure this really counts, since it's going to be a fixed numeric value *cast* to a pointer that is then dereferenced (something like "(*(volatile uint8_t *)0x25)" if you fully expand it), and accessing it should be exactly the same as accessing any other variable located at a fixed address, even though it uses pointer syntax behind the scenes.

In ARM and other processors you often have pointers to structs for peripherals, hence you wind up using lots of stuff like SPI2->DATA, which tends to make for nicer syntax than the AVR style, and means you can do things like store a pointer to a peripheral instance which can be handy for decoupling.  If you have a situation where you need to implement the same protocol on more than one interface, it's usually convenient to package up any state data or buffers into a struct for each protocol instance, and then pass a pointer to that struct into the functions that implement the protocol logic.  That struct can even contain a pointer to a USART or whatever to indicate which peripheral is associated with which protocol instance.  Or if those instances need to do slightly different things, you can store pointers to functions in the instance data.  This is really useful for supplying platform-dependent drivers to higher level libraries, especially libraries that may be used on different physical layers in the same application, for instance fatfs which may target both on-board flash and an SD card.
 

Online Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11622
  • Country: my
  • reassessing directives...
Re: [C] Pointers - what is the point?
« Reply #37 on: July 17, 2018, 01:15:43 am »
just as someone said... if you dont know whats its for, you dont need it.
Nature: Evolution and the Illusion of Randomness (Stephen L. Talbott): Its now indisputable that... organisms “expertise” contextualizes its genome, and its nonsense to say that these powers are under the control of the genome being contextualized - Barbara McClintock
 

Offline sleemanj

  • Super Contributor
  • ***
  • Posts: 3024
  • Country: nz
  • Professional tightwad.
    • The electronics hobby components I sell.
Re: [C] Pointers - what is the point?
« Reply #38 on: July 17, 2018, 01:21:12 am »
* Machine registers, those are all effectively pointers in C (eg in AVR land, volatile uint8_t *)
I'm not sure this really counts,

Plenty of situations in which you need to pass registers around at runtime, pointers (and the address operator) are the way in which to do that...

Code: [Select]
  function doTheThingOnThisRegister(volatile uint8_t *TheRegister) { *TheRegister = ..... }
  doTheThingOnThisRegister(&DDRB);




~~~
EEVBlog Members - get yourself 10% discount off all my electronic components for sale just use the Buy Direct links and use Coupon Code "eevblog" during checkout.  Shipping from New Zealand, international orders welcome :-)
 

Offline Leiothrix

  • Regular Contributor
  • *
  • Posts: 104
  • Country: au
Re: [C] Pointers - what is the point?
« Reply #39 on: July 17, 2018, 01:50:41 am »
just as someone said... if you dont know whats its for, you dont need it.

That's a bit of a bad outlook on life though.

If you don't know what it's for -- find out.  Then you can make an informed decision as to whether you need it or not.
 
The following users thanked this post: rs20

Offline T3sl4co1l

  • Super Contributor
  • ***
  • Posts: 21658
  • Country: us
  • Expert, Analog Electronics, PCB Layout, EMC
    • Seven Transistor Labs
Re: [C] Pointers - what is the point?
« Reply #40 on: July 17, 2018, 02:04:42 am »
Of interest:



Watch the series, hopefully it will prove illuminating. :)

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

Online ajb

  • Super Contributor
  • ***
  • Posts: 2601
  • Country: us
Re: [C] Pointers - what is the point?
« Reply #41 on: July 17, 2018, 02:22:17 am »
Plenty of situations in which you need to pass registers around at runtime, pointers (and the address operator) are the way in which to do that...
My point was the fact that the IO register is declared as a pointer doesn't mean that it gets used as one (especially because the dereference is part of the #define in the AVR style!).  In your example you even show that you need to convert it back to a pointer via & before passing it as a reference, so syntactically that's no different than if the IO register were defined as volatile uint8_t foo instead of *((volatile uint8_t *)foo).  The pointer syntax is only used in the device header files to put the symbol at a particular address without having to do ugly things with the linker.

Sidenote: Using pointer syntax for things that aren't normally used as pointers can become significant in other situations, such as when a peripheral register needs to be cast to a different type in an assignment--some peripherals exhibit different behavior depending on the width of the access to a register, so you might need to force an 8-bit access on a 32-bit register to get the desired behavior.  Reading is no big deal, something like foo = (volatile uint8_t)(SPI2->DR) works fine, but (volatile uint8_t)(SPI2->DR) = foo does NOT work, because you can't cast an lvalue--unless you convert it to a pointer first, which leads to the silly-looking but quite useful *((volatile uint8_t *)(&SPI2->DR)) = foo, which works fine.

Unrelated to the above, but another situation pointers are useful is if you need to return more than one item from a function--for instance, you can have the function directly return the requested value in the usual way, but you can also pass it a pointer to a location where it might store an error code, or the number of bytes written, or something like that.
« Last Edit: July 17, 2018, 02:23:54 am by ajb »
 

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3143
  • Country: ca
Re: [C] Pointers - what is the point?
« Reply #42 on: July 17, 2018, 02:24:30 am »
Start from the beginning.

Every variable has 4 major attributes:

- address - where the variable is located at the memory
- size - how much memory it occupies
- content - what the memory stores
- type - how to interpret the content

Pointer is simply a variable that holds the address of another variable. You use pointers any time you need to remember where a particular variable is. If you know the address of a variable, you can get to the variable, fetch its content or replace the content with something new. The same as if you meet a girl, you need to write down her address so that you can find her in the future.

Even if you don't use pointers, variables still have addresses. You need the address to get to any variable. But if the address is known at the compile time, the compiler can find the variable without your help. If not, you must use pointers.

 
The following users thanked this post: jpanhalt

Online Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11622
  • Country: my
  • reassessing directives...
Re: [C] Pointers - what is the point?
« Reply #43 on: July 17, 2018, 02:26:51 am »
just as someone said... if you dont know whats its for, you dont need it.

That's a bit of a bad outlook on life though.

If you don't know what it's for -- find out.  Then you can make an informed decision as to whether you need it or not.
you like to keep busy. Congratulation i'm not that man enough... read on..
Nature: Evolution and the Illusion of Randomness (Stephen L. Talbott): Its now indisputable that... organisms “expertise” contextualizes its genome, and its nonsense to say that these powers are under the control of the genome being contextualized - Barbara McClintock
 

Offline BravoV

  • Super Contributor
  • ***
  • Posts: 7547
  • Country: 00
  • +++ ATH1
Re: [C] Pointers - what is the point?
« Reply #44 on: July 17, 2018, 02:28:31 am »
Not an expert, example cases where pointer excels compared to array (assuming no constraint within small memory like MCU and the "link" it self cause no significant overhead to the overall memory usage).

Say "at run time", you need the bulk data stored which in the array (in OP's case) needs to be constantly resized either grow or shrink dynamically, linked list will beat array as the size is fixed.

Also at the sorted bulk data, manipulating like inserting/deleting data "in the middle" of the sorted bulk data, linked list will excels compared to array.

Offline T3sl4co1l

  • Super Contributor
  • ***
  • Posts: 21658
  • Country: us
  • Expert, Analog Electronics, PCB Layout, EMC
    • Seven Transistor Labs
Re: [C] Pointers - what is the point?
« Reply #45 on: July 17, 2018, 02:45:53 am »
* Machine registers, those are all effectively pointers in C (eg in AVR land, volatile uint8_t *)
I'm not sure this really counts, since it's going to be a fixed numeric value *cast* to a pointer that is then dereferenced (something like "(*(volatile uint8_t *)0x25)" if you fully expand it), and accessing it should be exactly the same as accessing any other variable located at a fixed address, even though it uses pointer syntax behind the scenes.

AVR GCC normally compiles such accesses (especially more than one access at a time) into literal pointer arithmetic (i.e., setting the X or Y registers to the base address, adding the offset and reading/writing SRAM there).  I forget if these are reduced to immediate addresses with heavy optimization.

It's a useful paradigm to understand a compiler as a translation tool, so that you can specify, in high level terms, what you want the output machine code to do.  Rather than writing it yourself, you tell it what to write.  In that sense, pointers are just another part of the tool at your disposal, and the point is to use them anywhere it makes your job easier, faster and more powerful. :)  Admittedly, this perspective isn't so useful to a beginner not familiar with instruction sets...

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

Online JPortici

  • Super Contributor
  • ***
  • Posts: 3461
  • Country: it
Re: [C] Pointers - what is the point?
« Reply #46 on: July 17, 2018, 07:25:18 am »
Meanwhile I'd like to suggest to Simon to buy a good book about programming C for microcontrollers. Judging by his other questions he is using mostly 8 bit controllers and on those pointers are better to be avoided anyway because they are slow. On a typical 8 bit microcontroller it is faster to use global variables (*). In general it is good to avoid pointers because they offer a myriad of ways to shoot yourself in your feet and problems are hard to debug. Range checking when accessing arrays is highly recommended.

IMHO the way array variables are automatically pointers in C isn't very consequent. After all a 'regular' variable could be seen as an array with only one element. This tends to confuse people because you see things like this:
Code: [Select]
int a;
int b[2];
memset(&a, 0, sizeof(a));
memset(b, 0, sizeof(b));

* On 16 and 32 bit platforms pointers are much faster because (usually) the memory layout and/or instruction set are better suited to use pointers.

agree with every single word.
Other that i sometimes use pointers to variable or structures in my PIC18 firmwares, i can spare some cycles and it's better to have to keep/update/debug one function instead of every copy of the same. Also fewer lines to read and check
 

Online newbrain

  • Super Contributor
  • ***
  • Posts: 1719
  • Country: se
Re: [C] Pointers - what is the point?
« Reply #47 on: July 17, 2018, 07:40:03 am »
Meanwhile I'd like to suggest to Simon to buy a good book about programming C
I left out the "for microcontrollers" part, but I think this is good advice to Simon.

Simon, I see you asking many disparate questions, from syntax to semantics to IDE use.
The forum is of course a great resource, and many are eager to help with high-quality answers, but some more structure and progression is IMHO needed.

IIRC you mentioned to have the K&R in another thread, I really think you should take the time to go through it, follow the examples and work out the exercises - even the banal ones - and make sure a topic is understood for good before proceeding.

The book is not MCU oriented, and will not help with IDE settings, but many things will get step by step clearer, and this will help having a better mental picture of the language, applicable to both embedded and hosted applications.

 :blah: I hope I don't sound too patronizing... :blah:
Nandemo wa shiranai wa yo, shitteru koto dake.
 

Online Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11622
  • Country: my
  • reassessing directives...
Re: [C] Pointers - what is the point?
« Reply #48 on: July 17, 2018, 08:49:08 am »
The book is not MCU oriented, and will not help with IDE settings..
there is the love to programming, there is the love to completing a project in due time. we know he's been in a serious professional business industry and been programing for a while but keep asking fundamental things recently, and complained how his sources are not for embedded programming he loved to. so i suspect he's into "learn if needed" basis. i have "C++ Nuts & Bolts: For Experienced Programmers" book. dont get scared by the term "Experienced" its not, the right term should be replaced with "Complete Guide", its the one i will grab if i forgot or got confused by the C/C++ syntaxes. its less than an inch thick, i think if i'm zero, i can complete the self-learnt course using the book alone in a month or so (and i have 5 childrens :P)...

only drawbacks is it lacks of practical and complete working examples let alone embedded, just examples needed to demonstrate the usage of each C/C++ keywords and syntaxes, from the basic pointers and arrays to the witchery of polymorphism, so we need some imagination there. the 2nd drawback is its heavily C++ oriented programming style with alot of "cout <<" that i hate, so you need to familiarize with C coding style and then differentiate which is C++ specific that cant be used in C style. if i'm like Simon i think i wont have trouble since i already have some basic experience programming C. fwiw.
Nature: Evolution and the Illusion of Randomness (Stephen L. Talbott): Its now indisputable that... organisms “expertise” contextualizes its genome, and its nonsense to say that these powers are under the control of the genome being contextualized - Barbara McClintock
 

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6242
  • Country: fi
    • My home page and email address
Re: [C] Pointers - what is the point?
« Reply #49 on: July 17, 2018, 09:12:55 am »
don't have malloc
The code was just a quick example I whipped up to explain the logic. You don't need malloc() for pointers to be useful in the pattern shown.

For microcontrollers, you'd use a static array of structures per type; typically 2 or 3 elements. When not used, you'd set their type to e.g. UNUSED or other reserved type enum, so that instead of a malloc call, you just loop over the array to find an unused one.

If you consider a microcontroller that responds asynchronously to multiple requests -- say, reading digital temperature sensors, setting the duty cycle of some PWM outputs, and such --, a queue of such commands or requests makes a lot of sense. If you need different requests to have different priorities, you can implement that too with a binary heap, quite effectively. In that case, the elements just need two pointers (left and right), instead of one (next).  (The code is obviously different. In any case, a binary heap is surprisingly efficient to manage.  On the other hand, if you only have something like a dozen or so possible nodes, it won't matter much how you deal with them, as it is just a few cycles per node access.)

For Simon and others learning how to do C in an embedded or freestanding environment, it means that unless and until you need to implement such algorithms to really get the hardware working the way you want, you probably won't see the utility of pointers.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf