C Programming: pointers

Status
Not open for further replies.
The big difference between the two is that arrays are compile time LABELS (address abstraction). You can't do runtime operations on a LABEL, so an array has to be indexed by a variable but pointers are variables that can be manipulated directly. This difference at times can make using arrays better for simple runtime indexing operations.
 
Last edited:
How about functions like this:

C:
void process_string_before_displaying(char * str) {
   // complicated conversion here
}

If not for the pointer, you would have to write a separate routine for each variable.

Yes! By using pointers, unions and structures instead of LABELS to memory it's possible to generalize functions and change execution context with only a single variable operation.
 
NorthGuy said:
If not for the pointer, you would have to write a separate routine for each variable.

3v0 is correct.. You don't have to use pointers when dealing with arrays... Strings are character arrays when all said and done, and declaring an array is the same as declaring a pointer to same...

Both of these are the same..
C:
char LCDbuff[17];
char * ptr = &LCDbuff[0];

ptr[3] is the same as LCDbuf[3]. So access is identical

But as you so rightly say.... The use of pointers on strings does make the process that little bit easier.
 
Agreed, I did not say the should never be used.


On an 8 bit micro it's sometimes shocking the difference in code generated using arrays vs using pointers even if they look the same at the source level. Arrays are less general but usually the best choice when not really needed due to the code generated when using pointers. Because the array is a LABEL and NOT a variable the compiler can use precomputed addresses in the assignment in this simple example

C18 extended mode:

Code:
void main(void)
{
far char LCDbuff[17],a;
far char * ptr = &LCDbuff[0];

a=LCDbuff[3];
a=ptr[3];
a=0;
}

Generated code:
Code:
80:            void main(void)
00A6  CFD9    MOVFF FSR2L, POSTINC1
00A8  FFE6    NOP
00AA  CFE1    MOVFF FSR1L, FSR2L
00AC  FFD9    NOP
00AE  E981    SUBFSR 2, 0x1
00B0  E854    ADDFSR 1, 0x14
81:            {
82:            far char LCDbuff[17],a;
83:            far char * ptr = &LCDbuff[0];
00B2  50D9    MOVF FSR2L, W, ACCESS
00B4  0F01    ADDLW 0x1
00B6  6EE6    MOVWF POSTINC1, ACCESS
00B8  CFDA    MOVFF FSR2H, POSTINC1
00BA  FFE6    NOP
00BC  52E5    MOVF POSTDEC1, F, ACCESS
00BE  50E5    MOVF POSTDEC1, W, ACCESS
00C0  6E14    MOVWF [0x14], ACCESS
00C2  50E7    MOVF INDF1, W, ACCESS
00C4  6E13    MOVWF [0x13], ACCESS
84:          
85:            a=LCDbuff[3];
00C6  EB84    MOVSS 0x4, 0x12
00C8  F012    NOP
86:            a=ptr[3];
00CA  0E03    MOVLW 0x3
00CC  2413    ADDWF [0x13], W, ACCESS
00CE  6EE9    MOVWF FSR0L, ACCESS
00D0  0E00    MOVLW 0x0
00D2  2014    ADDWFC [0x14], W, ACCESS
00D4  6EEA    MOVWF FSR0H, ACCESS
00D6  50EF    MOVF INDF0, W, ACCESS
00D8  6E12    MOVWF [0x12], ACCESS
87:            a=0;
00DA  6A12    CLRF [0x12], ACCESS
88:            }
 
Anyway there is no point in using pointers in c where you can use an array. Pun intended.

When you write a value in a register like this:

PORTC = 0xFF;

You are using a pointer.

Just try to code C without using pointers. Almost impossible.
 

You can test that with the sizeof -operator:

C:
char LCDbuff[17];
char* ptr =&LCDbuff[0];

sizeof(LCDbuff); // Result will be 17, the length of the array in bytes

sizeof(ptr); // result will be the size of a memory address in bytes. Probably 2.
 
For example, if you have a variable and a routine that needs to modify the variable, instead of passing the variable to the routine, you pass the pointer to the variable. I have absolutely no idea how you can do this simple thing without pointers.

That's about as far (no pun intended) I would use them too.

As for Unions posted by Ian Rogers, Good in principle, but totally makes none portable code depending on whether you are using Big or Little Endian processors as they are handled differently.
 
 
And on another thing, most high level programmers I meet have no idea on code optimising. No idea of direct and indirect instructions. They just malloc(everything available) and mess about with it to get it to run.
I would sack the lot of them given the choice. Maybe it's a sign of our new graduate engineering students and their educational capacity.
 
WTP said:
As for Unions posted by Ian Rogers

I only ever use unions for serialisation... Best thing ever for sending stuff Ic to Ic..
 
I agree as the code access the variables as part of a long by address (for example), but our Coding Police for Standards think you should shift each part of interest into a char and send that despite having no understanding of what's going on "under the hood" and knowing the overhead of un-needed instructions.
 

Using shifting instead of pointers guarantees correct endianness. This is good practice because one important idea behind C is portability.

If you send a 32 bit variable through UART like this:
C:
float variable = 3.141592; // 32 bit float
char* p = (char*)(&variable); // Take address of variable and cast to char-pointer
send(p[0]); // send byte
send(p[1]);
send(p[2]);
send(p[3]);
That looks nice. But you can't say which byte is sent first (just by reading code).. the MSB or LSB.

Shifting and casting to char is more safe (for portability):
C:
send((char)((variable>>0) & 0xFF)); // send LSB
send((char)((variable>>8) & 0xFF));
send((char)((variable>>16) & 0xFF));
send((char)((variable>>24) & 0xFF)); // send MSB

But now, for those who were saying pointers are useless, which one is more readable code?
 
Last edited:
I don't think that portability is important in the embedded world because programs are small and very hardware specific.

Try to compile your examples, look at the assembler code. Wouldn't it be easier to write a slightly more efficient and much less cryptc code in assemler?
 
Of course, there's absolutely no doubts that this:

C:
send((char)((variable>>0) & 0xFF)); // send LSB
send((char)((variable>>8) & 0xFF));
send((char)((variable>>16) & 0xFF));
send((char)((variable>>24) & 0xFF)); // send MSB

is way easier to write than this:

Code:
mov #variable, w0
mov #4, w1
rcall uart1_send

And everyone who thinks differently is a complete idiot (The last two words need to be repeated several times so that clever people would understand better)
 
Direct assembly applications programming is boring! (fixing systems programming bugs in ASM from memory dumps is not much better) Been there, done that, about 40 years ago. If children want to play with mud bricks to build a doll house that's good as it's all a part of growing up.
 
Last edited:

Programming is not about "how easy it is to write". It is about structure, abstraction, modularity, managing big projects, working in teams and passing the work to the next guy to continue. Without these things you can't build "big" things.
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…