Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

C programming pointer explanation needed

Status
Not open for further replies.

glenjoy

Banned
Advanced Member level 3
Joined
Jan 1, 2004
Messages
962
Helped
72
Reputation
146
Reaction score
20
Trophy points
1,298
Location
Philippines
Activity points
0
I encountered this prblem in the book C How to program, and too bad, there is no clear explanation how this happened.

Here is the code:

Code:
#include <stdio.h>


int main()
{

char sentence[80];
void reverse(const char * const);

printf("Enter a line of text:\n");
gets(sentence);

printf("\nThe line printed backwards is:\n");
reverse(sentence);

return 0;

}

void reverse(const char * const sPtr)
{

if(sPtr[0] == '\0')
return;
else
{

reverse(&sPtr[1]);
putchar(sPtr[0]);

}

}

Can someone explain me how the code works, by dissecting it, thanks.
 

The "trick" is done with the recursive call of reverse(); each time it is called, the line "reverse(&sPtr[1]);" performs an a increment of the pointer due recursion. Thus, when the first call to reverse() it start printing the last char and so on.

Is that the type of answare you are looking for?

Regars,

dpsm
 

    glenjoy

    Points: 2
    Helpful Answer Positive Rating
dpsman said:
The "trick" is done with the recursive call of reverse(); each time it is called, the line "reverse(&sPtr[1]);" performs an a increment of the pointer due recursion. Thus, when the first call to reverse() it start printing the last char and so on.

Is that the type of answare you are looking for?

Regars,

dpsm

A good answer but not a very clear one, maybe you can explain more on how the reverse function works, by stating the contents of the string and array and how they are modified, just got really confused with the statement:
Code:
 reverse(&sPtr[1])

& as I understand is used to get the address of memory location and store it to a pointer.


The function reverse(const char * const sPtr) already has sPtr has its variable, does this mean get the address of sPtr? And what is with the sPtr[1]?
 

The value of a pointer is an address.

Assuming you have
const char * sentence="ab\0";

This is the same as saying
sentence[0]='a';
sentence[1]='b';
sentence[2]='\0';

Now, we use
const char * sentence1=&sentence[1];
This is the same as saying
sentence1[0]='b';
sentence1[1]='\0';

Now, we use
const char * sentence2=&sentence1[1];
This is the same as saying
sentence2[0]='\0';

Now, the if condition is satisfied and the function returns to the previous reverse function that is called. The next line asks for sentence1[0] to be printed and returns to the previous reverse function that is called. The nest line again asks for sentence[0] to be printed before returning to the very first reverse function call, which was called from the main function.

Hope this is clear enough.
 

    glenjoy

    Points: 2
    Helpful Answer Positive Rating
Hi glenjoy,

I think you should write this row "void reverse(const char * const);" before main function.

regrads,
 

asahin11 said:
Hi glenjoy,

I think you should write this row "void reverse(const char * const);" before main function.

regrads,

Yes thank you, my question is about recursion not compilation error.

Ok, here is another example:

Code:
#include <stdio.h>

void wrt_it(void);

int main(void)
{
printf("Input a line:");
wrt_it();
printf("\n\n");
return 0;
}

void wrt_it(void)
{
int c;

if((c=getchar()) != '\n')
wrt_it();
putchar(c);
}

Now here is what I have read from the book, this example came from C by Al Kelley and Ira Pohl, every time wrt_it(); is called, it creates a local variable c, not conflicting with other c variable created because it is at different stack.

Now my question is, it is very clear that once a '\n' is pressed, everything will be typed backwards, yes that will be true because as stated each function will be released now from the stack, last in, first out, the confusing part is the '\n' or RETURN key is only pressed once, how come all the functions are released in one key press of RETURN key, must it not be every content of variable c must be displayed only in every press of RETURN key?

Thanks.

For the useful replies, you got a HELPED ME point.
 

Hello,
Dpsman's & Checkmate's answers are absolutely correct.

First of all: I tried to run the code with the following modifications & it ran.
1.
Code:
void reverse(const char * const);
=>
Code:
void reverse(const char * );
2.
Code:
void reverse(const char * sPtr)
=>
Code:
void reverse(const char * sPtr)
Second: lets look at the function call in the body of main.
Code:
reverse(sentence);
The array name is the pointer to its first element.
Third: the operation of the reverse function.
The function checks if that is the last element of the string & returns if it is
Code:
if(sPtr[0] == '\0') 
return;
If not, it calls it self again & the print line will never be executed till the called function returns. The first time it will return when it finds the null character & then starts printing from the last element to the first one.
Code:
else 
{ 

reverse(&sPtr[1]); 
putchar(sPtr[0]); 

}
& thats why it reverses printing.
Fourth: regarding the line reverse(&sptr[1]).
sptr[1] is the same as * (sptr ++) =2 getting the data in the next position.
The ambersand just gets the pointer to this element as reverse is defined that it takes a pointer.

The most ambigious is why did the coder used the const modifiers with both the first item in my answer & before the pointer itself
void reverse(const char * const sPtr)
Let us look at the following example:
Code:
const myage= 35;
Although it is a constant variable it can be indirectly modified through the pointer:
Code:
*(int *) &myage =35;
But in this code he used the const modifier with the pointer itself in addition to the variable giving no way to change the pointer itself & no way to change the data it points to.

Added after 17 minutes:

the confusing part is the '\n' or RETURN key is only pressed once, how come all the functions are released in one key press of RETURN key, must it not be every content of variable c must be displayed only in every press of RETURN key?

Look carefully at the function & suppose i am entering the word amr & the press enter
Code:
void wrt_it(void) 
{ 
int c; 
if((c=getchar()) != '\n') 
wrt_it(); 
putchar(c); 
}

I type a the function creates its own variable c_1 & finds it is not equal to '\n' then it suspends printing c_1 & calls itself again & creates its own variable c_2& finds it is not equal to '\n' then it suspends printing c_2 & calls itself again & creates its own variable c_3& finds it is not equal to '\n' then it suspends printing c_3 & calls itself again creates its own variable c_4& finds it equal to '\n'. This time it does not call here self it puts c_4 to the screen & returns to the caller one which resumes executing at printing c_3 & returns to the caller one that prints c_2 & returns to the caller one that prints c_1
 

    glenjoy

    Points: 2
    Helpful Answer Positive Rating
What you mean is that the program or function stopped at wrt_it(); and was not able to execute putchar(c);, then when '\n' was encountered, the entry point for all the functions suspended or waiting in the stack will have an entry point at putchar(c);?

Is this right?

Thank you very much.
 

the entry point for all the functions suspended or waiting in the stack will have an entry point at putchar(c);?


Yes thats absolutely right.

Regards,
Amr.

Added after 50 minutes:

asahin11 wrote:
Hi glenjoy,

I think you should write this row "void reverse(const char * const);" before main function.

regrads,
You do not need to, I compiled it with Borland C++ compiler & it did not show any problems.
 

    glenjoy

    Points: 2
    Helpful Answer Positive Rating
Your first programm if does not have constant variables it could be like this doing the same work :

-------------------------------------------------
#include <stdio.h>

void reverse(char*);

int main()
{

char sentence[80];

printf("Enter a line of text:\n");
gets(sentence);

printf("\nThe line printed backwards is:\n");
reverse(sentence);

gets(&sentence[0]);
return 0;
}

void reverse(char *sPtr)
{

if(*sPtr == '\0')
return;

else
{
reverse(++sPtr);
putchar(*--sPtr);
}

}
-------------------------------------------------
Maybe this helps you .
 

m_t_blind wrote:
Your first programm if does not have constant variables it could be like this doing the same work.
The const modifiers are used to fully protect the eneterd scentence.
In this code he used the const modifier with the pointer itself in addition to the variable giving no way to change the pointer itself & no way to change the data it points to.
See the example I gave before.

Regards,
Amr.
 

amraldo said:
The const modifiers are used to fully protect the eneterd scentence. In this code he used the const modifier with the pointer itself in addition to the variable giving no way to change the pointer itself & no way to change the data it points to.

I agree with you, i said that this programm is working without constand variables, and i gave it for comparison to the original, and for uderstanding the correspondence between tables and pointers.
 

I like to think of recursion this way. Recursive calls add to a stack. Each recursive call adds the next set of variables to a stack. In the first example (reverse), the recursive calls place the characters on a stack until it reaches the end of the string. Then, it pops the stack and prints the character off the top of the stack (which is the last character you placed on the stack). The order of commands in reverse is important, because you must print the character AFTER you have placed it on the stack.

Everyone had it figured out, but I thought I'd say it differently so someone may benefit....?
 

Code:
void reverse(const char * const sPtr) 
{ 

if(sPtr[0] == '\0') 
return; 
else 
{ 

reverse(&sPtr[1]); 
putchar(sPtr[0]); 

} 

}

here pointers are not doing any majic, but recursion.

let us take a string "abcd"

when reverse is called first it function reverse should print 'a'
when reverse is called next it function reverse should print 'b'
when reverse is called next it function reverse should print 'c'
when reverse is called next it function reverse should print 'd'

as reverse(&sPtr[1]) points to next character each time

the sequential calls reverse is not complete in last sequence reverse is called recursively. But the complete data is there in stack.

Next reverse call ends as next character is '\0'

Now rest of the reverse function completes from last called to first called. that means it starts printing 'd' -> 'c' -> 'b' -> 'a'

Is ot OK, correct me if I am wrong. :D
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top