C: Do you have a pointer about pointers (in C)

For discussions about programming, and for programming questions and advice


Moderator: Forum moderators

Post Reply
User avatar
cobaka
Posts: 521
Joined: Thu Jul 16, 2020 6:04 am
Location: Central Coast, NSW - au
Has thanked: 87 times
Been thanked: 49 times

C: Do you have a pointer about pointers (in C)

Post by cobaka »

hello all & woof.

I'm learning C, so with that in mind you know where I am at this moment.
I'm asking about the appearance of pointers in C program source.
In Pascal, pointers were often designated with the caret "^" character, so an array pointer may appear in a program as ^array.
Just a single variable that is a point to something.

The C manual says:

To declare a pointer, include the indirection operator (see Section 3.10 [Pointer Operators], page 35) before the identifier. Here is the general form of a pointer declaration:
data-type * name;
Then White space is not significant around the indirection operator:
data-type *name;
data-type* name;

The asterisk need not be part of the variable name.

Recently I came across a program where every pointer (or indirection operator) appeared separately, thus:
FILE * listfile,* objfile; or
char * srcptr; /* Pointer to line being parsed */

I understand - to a degree why this is done. Pointers are variables with a specific role - they "point".
Unlike Pascal, the C language cannot use the caret character to denote a pointer.
The first char in variable names must be alphabetic or (the exception) "_" underscore. So - no caret.
(I note that "*" breaks the "must be alphabetic" rule ... but hey! This is computer science, right?)

Now - my question (it's trivial, but bugging me!)
Why would anyone write code where the indirection operator ("*") is separated by a space from the rest of the pointer name?
Why not make a rule that all pointer names are written thus: *free_ram?

cobaka

собака --> это Русский --> an old dog
"so-baka" (not "co", as in coast or crib).

step
Posts: 516
Joined: Thu Aug 13, 2020 9:55 am
Has thanked: 50 times
Been thanked: 184 times
Contact:

Re: Do you have a pointer about pointers (in C)

Post by step »

Why? Largely for style, I'd say. But also consider that * for pointers is an _operator_ just like, e.g. +, -, /, etc. are math operators, and some people like to write 1+1 while others 1 + 1. Just remember that no matter how many spaces you add, what matters is operators precedence, just like 1+2 * 3 isn't going to yield 9 ever (I didn't make an equivalent pointer example, because I don't know how far is your C yet, but and example can be made).

User avatar
wiak
Posts: 3673
Joined: Tue Dec 03, 2019 6:10 am
Location: Packing - big job
Has thanked: 57 times
Been thanked: 1028 times
Contact:

Re: Do you have a pointer about pointers (in C)

Post by wiak »

cobaka wrote: Thu Jul 28, 2022 1:09 am

Now - my question (it's trivial, but bugging me!)
Why would anyone write code where the indirection operator ("*") is separated by a space from the rest of the pointer name?
Why not make a rule that all pointer names are written thus: *free_ram?

Because the name is the name of the variable itself. So in the above free_ram is the variable name, and the * just tells you that this particular variable is used to store addresses to other variables (i.e. a pointer). And the contents of any such pointer variable can point to another pointer variable if you wish (only if type matches though... you'll find out in experiments...); so it is possible to have something like a pointer to a pointer of type char, for example.

Example:

Code: Select all

char *myvar, apple='A', lemon[20], *orange;
int i

In the above, the C compiler will parse the variable definitions and is clever enough to note the * and therefore realizes that what follows (myvar) defines a pointer type of variable whether a space used inbetween or not.
The variable apple does not have any * in front of it so it is not a pointer type of variable, but instead can hold a single character (such as 'A'), which is really a small integer of size 256bits (i.e. 0 to 255, being 00 to FF in hex notation).
Variable lemon is a char array of 20 max characters. An actual string stored in there would be terminated with ASCII 0, which is \0.

You can actually assign one pointer to another like this:

Code: Select all

orange = grape;

since orange is also a pointer to type char

and then use:

Code: Select all

printf("%s\n", orange);

to print out the whole hello world string in the grape array per program below (which ends with the \0).

You cannot do the following directly in C though:

Code: Select all

lemon = "good day";

instead you need to use something like strcpy function:

Code: Select all

strcpy(lemon, "good day");

though if you already had say:

Code: Select all

char mystring[]="good day";

you could instead build up lemon char by char from mystring:

Code: Select all

for (i = 0; mystring[i] != '\0'; ++i) {
  lemon[i] = mystring[i];
}
lemon[i] = '\0';

Here is a quick example program. If stored as weeprog.c you can compile (simplest) with:

Code: Select all

gcc weeprog.c

and run the resulting a.out (assuming has execute permissions):

Code: Select all

./a.out

Code: Select all

#include <stdio.h>
#include <string.h>
int main() {
    /* some examples of using variables tho I didn't use some of them */
    char *myvar, apple='A', lemon[20], *orange;
    int num1, num2, i, *j;   // and so on...
    char grape[] = "hello world";
    // or could use: char grape[] = {'h','e','l','l','o',' ','w','o','r','l','d','\0'};
    char mystring[]="good day";
    // printf %s expects a pointer (address of start of string)
    printf("%s\n", &grape[0]); // hello world
    // the array name is the same as &grape[0]
    printf("%s\n", grape);       // hello world
    orange = grape;
    printf("%s\n", orange);     // hello world
    myvar = &apple;
    printf("%c\n", apple);      // A
    printf("%c\n", *myvar);    // A
    // use: strcpy(lemon,"good day");  or could use:
    for (i = 0; mystring[i] != '\0'; ++i) {
        lemon[i] = mystring[i];
    }
    lemon[i] = '\0';
    // but there are ways of writing above more with pointers
    printf("%s\n", lemon);     // good day
    return 0;
}

Could, for example, have used:

Code: Select all

    for (i = 0; *(mystring+i) != '\0'; ++i) {
        *(lemon+i) = *(mystring+i);
    }
    *(lemon+i) = '\0';

In this context, the * basically means "contents of".

You probably came across tutorialspoint. An example of pointer to pointer is given there, and more besides:

https://www.tutorialspoint.com/cprogram ... ointer.htm

I haven't written anything in C for years actually, but I used to love pointers (and even pointers to pointers to pointers... masochist maybe) - just one small step above assembly language really and could do a lot of things very fast just by re-organising pointers (for example in sort algorithms) rather than actually moving array contents about or making actual copies of them in memory. Drawing simple little memory diagrams/representations (boxes) helps a lot working out pointer tricks and operation - that's how old K&R C programming text actually explains their intracacies. You can stumble across copies of that online...

The C Programming Language 2nd Edition Ritchie Kernighan page 97:

In C, there is a strong relationship between pointers and arrays, strong enough that pointers and arrays should be discussed simultaneously. Any operation that can be achieved by array subscripting can also be done with pointers. The pointer version will in general be faster but, at least to the uninitiated, somewhat harder to understand.

By the time you'd reach page 114 of that book and checked out the diagrams you'd have complete understanding of that relationship and pointers more generally. That's exactly how I learned it - way back in 1990...

Also found some interesting comments here: https://www.quora.com/How-do-you-access ... nters-in-C

https://www.tinylinux.info/
DOWNLOAD wd_multi for hundreds of 'distros' at your fingertips: viewtopic.php?p=99154#p99154
Αξίζει να μεταφραστεί;

User avatar
cobaka
Posts: 521
Joined: Thu Jul 16, 2020 6:04 am
Location: Central Coast, NSW - au
Has thanked: 87 times
Been thanked: 49 times

Re: Do you have a pointer about pointers (in C)

Post by cobaka »

Thanks for the observations/instruction given earlier.

I came with some baggage from Pascal about pointers; that had to go.
In that language, the authors spent a good deal of energy 'isolating' the data types from the programmer and allowing no cross-over. C is different. On page 110 of K&R (1st edition) I read:

Pointers are not Integers
You may notice in older C programs a rather cavalier attitude toward copying pointers. It has generally been true that on most machines a pointer
may be assigned to an integer and back again without changing it; no scaling or conversion takes place, and no bits are lost. Regrettably, this has led to
the taking of liberties with routines that return pointers which are then merely passed to other routines the requisite pointer declarations are often left out.

It turns out then, that my question was not trivial at all - and the idea that I considered it trivial simply showed I did not grasp the concept completely. I should have done that; I spent more time programming assembly code than other languages.

On the topic of assembly - the 6809 is a processor where pointers are inherent in instruction set. I need say no more.

I have a copy of K&R - it is the first edition. I must update, although I find the GNU C manual and the GNU C tutorial informative. Starting with the index, at the end, I can almost always find the topic of interest with only a few clicks of the mouse. (I suspect that the page numbers in the index are a kind of pointer - not in the strict "C" language sense, but in general terms.)

Thanks to @step & @wiak for two informative answers to the "Q" that was bugging me!

собака

собака --> это Русский --> an old dog
"so-baka" (not "co", as in coast or crib).

User avatar
6502coder
Posts: 89
Joined: Mon Jul 13, 2020 6:21 pm
Location: Western US
Has thanked: 3 times
Been thanked: 20 times

Re: Do you have a pointer about pointers (in C)

Post by 6502coder »

There is another, more subtle reason for always binding the "*" to the variable name. It has to do with the declarations of variables.

The declaration

int *countPtr;

says that the variable "countPtr" is a pointer to an int.

The compiler will also accept

int* countPtr;

which one could argue also makes sense--you could read it as saying that "countPtr" is an "int-pointer," i.e. a pointer to an int.

The problem with the second style is that C newbs are then tempted to write

int* firstPtr, secondPtr, thirdPtr;

thinking that they have declared 3 pointers to int, when in fact they have declared only ONE pointer to int, along with two normal int variables. In other words, they are misled into thinking that "int*" is a type, which is it not. This second example can ONLY be written

int *firstPtr, *secondPtr, *thirdPtr;

Post Reply

Return to “Programming”