Unix/Linux Go Back    


Programming Post questions about C, C++, Java, SQL, and other programming languages here.

Pure C function pointer on printing vowels twice

Programming


Tags
c function pointer, logic or

Closed    
 
Thread Tools Search this Thread Display Modes
    #1  
Old Unix and Linux 05-17-2017   -   Original Discussion by yifangt
yifangt's Unix or Linux Image
yifangt yifangt is offline VIP Member  
UNIX.COM VIP Member
 
Join Date: Sep 2009
Last Activity: 7 December 2017, 5:47 PM EST
Location: Saskatchewan, Canada
Posts: 516
Thanks: 332
Thanked 8 Times in 8 Posts
Pure C function pointer on printing vowels twice

Have difficulty to understand this pure C code to only print vowels twice from input string. Questions are commented at the end of each place.

Code:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
/*
 *Demonstrate the use of dispatch tables
 */

/*Print a char twice like putchar, return char if successful, or EOF on error.*/

int putcharTwice(int c)
{
    if (putchar(c) == EOF || putchar(c) == EOF)  {//Q1
    return EOF;
    } else {
    return c;
    }
}

#define NUM_CHARS (UCHAR_MAX + 1)    //UCHAR_MAX is in limits.h

int main(int argc, char **argv)
{
/*This declares table as array of function pointers */
    int (*table[NUM_CHARS]) (int);   //Q2
    int i;
    int c;

    for (i = 0; i < UCHAR_MAX; i++) {
    /* default is to call putchar */
    table[i] = putchar;
    }

    /*but lower-case vowels show up twice */
    table['a'] = putcharTwice; //Q3, and following 4 lines
    table['e'] = putcharTwice; //Q3
    table['i'] = putcharTwice; //Q3
    table['o'] = putcharTwice; //Q3
    table['u'] = putcharTwice; //Q3

    while ((c = getchar()) != EOF) {
    table[c] (c); //Q4,
    }
    return 0;
}

The code was compiled without any problem,

Code:
$ echo "The quick brown fox jumps over the lazy dog!" | ./a.out
$ Thee quuiick broown foox juumps ooveer thee laazy doog!

Q1: How does the logic work by repeating the same condition on both sides of "||" ? I tried using only one side of the OR condition, the code compiled without error but did not work as expected.

Q2:Even not quite sure how to ask this question. Is this a prototype of a function? But the calling is without any parameter see Q3.

Q3: Calling of the function does not have a parameter at all. How does it work?

Q4: I thought I understand this line, but I must have wrong catch because of Q2.

Thanks a lot!
Sponsored Links
    #2  
Old Unix and Linux 05-17-2017   -   Original Discussion by yifangt
Don Cragun's Unix or Linux Image
Don Cragun Don Cragun is offline Forum Staff  
Administrator
 
Join Date: Jul 2012
Last Activity: 15 December 2017, 3:21 AM EST
Location: San Jose, CA, USA
Posts: 10,784
Thanks: 590
Thanked 3,772 Times in 3,220 Posts
Quote:
Originally Posted by yifangt View Post
Have difficulty to understand this pure C code to only print vowels twice from input string. Questions are commented at the end of each place.

Code:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
/*
 *Demonstrate the use of dispatch tables
 */

/*Print a char twice like putchar, return char if successful, or EOF on error.*/

int putcharTwice(int c)
{
    if (putchar(c) == EOF || putchar(c) == EOF)  {//Q1
    return EOF;
    } else {
    return c;
    }
}

#define NUM_CHARS (UCHAR_MAX + 1)    //UCHAR_MAX is in limits.h

int main(int argc, char **argv)
{
/*This declares table as array of function pointers */
    int (*table[NUM_CHARS]) (int);   //Q2
    int i;
    int c;

    for (i = 0; i < UCHAR_MAX; i++) {
    /* default is to call putchar */
    table[i] = putchar;
    }

    /*but lower-case vowels show up twice */
    table['a'] = putcharTwice; //Q3, and following 4 lines
    table['e'] = putcharTwice; //Q3
    table['i'] = putcharTwice; //Q3
    table['o'] = putcharTwice; //Q3
    table['u'] = putcharTwice; //Q3

    while ((c = getchar()) != EOF) {
    table[c] (c); //Q4,
    }
    return 0;
}

The code was compiled without any problem,

Code:
$ echo "The quick brown fox jumps over the lazy dog!" | ./a.out
$ Thee quuiick broown foox juumps ooveer thee laazy doog!

Q1: How does the logic work by repeating the same condition on both sides of "||" ? I tried using only one side of the OR condition, the code compiled without error but did not work as expected.
putchar(c) returns 0 on success or EOF on error. So, if the first putchar(c) succeeds, the second putchar(c) will also be executed. If both of them succeed, the expression tested will be 0 || 0 and the else side of the if statement will have putcharTwice() return c. If either putchar(c) failed, putcharTwice() will return EOF.

Quote:
Q2:Even not quite sure how to ask this question. Is this a prototype of a function? But the calling is without any parameter see Q3.
int (*table[NUM_CHARS]) (int); is a declaration stating that table is an array of 256 pointers to functions and those functions take one argument of type int and return an int.

Quote:
Q3: Calling of the function does not have a parameter at all. How does it work?

Code:
    for (i = 0; i < UCHAR_MAX; i++) {
    /* default is to call putchar */
    table[i] = putchar;
    }

sets the 1st 255 of the 256 elements of the table[] array to be a pointer to the putchar() function. It does not call putchar().


Code:
    /*but lower-case vowels show up twice */
    table['a'] = putcharTwice;

resets the elements of the table[] array corresponding the the character a to point to the function putcharTwice(). And the following statements do the same thing for the other lowercase vowels in the English alphabet. These assignments do not call putchar() or putcharTwice() either.

Quote:
Q4: I thought I understand this line, but I must have wrong catch because of Q2.

Code:
    while ((c = getchar()) != EOF) {
    table[c] (c); //Q4,
    }

is a loop that reads one character at a time from standard input until it detects an error or end-of-file condition. For each character read, it calls the function specified by the element of table[] corresponding to the character read with an argument that is the character read.

Quote:
Thanks a lot!
Hope this helps.
The Following 2 Users Say Thank You to Don Cragun For This Useful Post:
wisecracker (05-17-2017), yifangt (05-17-2017)
Sponsored Links
    #3  
Old Unix and Linux 05-17-2017   -   Original Discussion by yifangt
yifangt's Unix or Linux Image
yifangt yifangt is offline VIP Member  
UNIX.COM VIP Member
 
Join Date: Sep 2009
Last Activity: 7 December 2017, 5:47 PM EST
Location: Saskatchewan, Canada
Posts: 516
Thanks: 332
Thanked 8 Times in 8 Posts
Thanks Don! I seem to get closer to understand it. With a simpler test, here is my dissection of the execution:
Code:
 $ echo Test | ./a.out 
table['T'] ~~> putchar('T');  
table['e'] ~~> putcharTwice('e');  
table['s'] ~~> putchar('s');
table['t'] ~~> putchar('t');

but I still did not get how putcharTwice( int c) print the chars (now vowels only) twice.
For putcharTwice('e'): (putchar('e') == EOF || putchar('e') == EOF) becomes (0 || 0) so that the else block is executed to return 'e'; but how is 'e' printed twice to have ee with this function?

Thanks again!

Last edited by yifangt; 05-17-2017 at 01:45 PM.. Reason: typo
    #4  
Old Unix and Linux 05-17-2017   -   Original Discussion by yifangt
Corona688's Unix or Linux Image
Corona688 Corona688 is offline Forum Staff  
Mead Rotor
 
Join Date: Aug 2005
Last Activity: 14 December 2017, 4:58 PM EST
Location: Saskatchewan
Posts: 22,547
Thanks: 1,159
Thanked 4,287 Times in 3,955 Posts
Quote:
but I still did not get how putcharTwice( int c) print the chars (now vowels only) twice.
Because putchar isn't returning EOF.
From man putchar:

Code:
RETURN VALUE
       fputc(),  putc()  and  putchar()  return  the  character  written as an
       unsigned char cast to an int, or EOF on error.

So if you're printing C, it ends up testing 'C' == EOF, which evaluates to 0, allowing it to reach the second part, testing 'C' == EOF again, which is false again.
Sponsored Links
    #5  
Old Unix and Linux 05-17-2017   -   Original Discussion by yifangt
yifangt's Unix or Linux Image
yifangt yifangt is offline VIP Member  
UNIX.COM VIP Member
 
Join Date: Sep 2009
Last Activity: 7 December 2017, 5:47 PM EST
Location: Saskatchewan, Canada
Posts: 516
Thanks: 332
Thanked 8 Times in 8 Posts
Is there another layer hidden behind for printing with putchar() in the if-condition?

The return value is EOF or a single vowel, which is the first part bugging me.

Does that mean in if (putchar(c) == EOF || putchar(c) == EOF) , function putchar(c) gets actually executed twice?

I thought this line is just a condition, and before the end only the else block is executed so that the value is 'e', without printing.
Let me put my question in another way:
Is there another layer for printing hidden behind, such as when 'e' is encountered in 'Test'?

Code:
putchar(c);    //Is this the place 'e' get printed the first time?
left ~> (putchar(e) == EOF) is false, 0
putchar(c);    //Is this the place 'e' get printed the second time?
right ~> (putchar(e) == EOF is false, 0
so that, the if (0 || 0) condition still false; 
else block executed

Is this correct?
Thanks!

Last edited by yifangt; 05-17-2017 at 04:26 PM..
Sponsored Links
    #6  
Old Unix and Linux 05-17-2017   -   Original Discussion by yifangt
Corona688's Unix or Linux Image
Corona688 Corona688 is offline Forum Staff  
Mead Rotor
 
Join Date: Aug 2005
Last Activity: 14 December 2017, 4:58 PM EST
Location: Saskatchewan
Posts: 22,547
Thanks: 1,159
Thanked 4,287 Times in 3,955 Posts
Quote:
Originally Posted by yifangt View Post
The return value is EOF or a single vowel, which is the first part bugging me.

Does that mean in if (putchar(c) == EOF || putchar(c) == EOF) , function putchar(c) gets actually executed twice?
Yes. To evaluate the expression, it has to call the function.

Quote:
I thought this line is just a condition
Slapping an if() around it doesn't change it. Would you expect this to print the values?


Code:
#include <stdio.h>

int main(void) {
    printf("a") && printf("b");
}

Treat anything inside an if() the exact same way.

Quote:
Let me put my question in another way:
Is there another layer
No.

For C, the answer to this question is always "no".

With very specific exceptions - like atexit() - C will never call a function without being asked.
Sponsored Links
    #7  
Old Unix and Linux 05-17-2017   -   Original Discussion by yifangt
yifangt's Unix or Linux Image
yifangt yifangt is offline VIP Member  
UNIX.COM VIP Member
 
Join Date: Sep 2009
Last Activity: 7 December 2017, 5:47 PM EST
Location: Saskatchewan, Canada
Posts: 516
Thanks: 332
Thanked 8 Times in 8 Posts
What I meant is: Does putchar(c) == EOF have two layers?
First,
putchar(c), which will print 'c' out;
Second, evaluate putchar(c) == EOF, which is false because first step is successful.
How does 'e' get printed twice in 'Test'? I need each step through the code.
i.e. how the function putcharTwice(int c) print each 'c' twice?

Thanks!

Last edited by yifangt; 05-17-2017 at 05:08 PM..
Sponsored Links
Closed

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Linux More UNIX and Linux Forum Topics You Might Find Helpful
Thread Thread Starter Forum Replies Last Post
Counting vowels in string. "Comparison pointer-integer". fakuse UNIX for Dummies Questions & Answers 1 12-06-2011 01:22 AM
Printing pointer address perleo UNIX for Dummies Questions & Answers 5 03-29-2011 02:43 PM
Function Returning Pointer majid.merkava Programming 6 03-22-2011 06:55 PM
Function pointer to inline function ? emitrax Programming 11 10-01-2009 04:59 AM
Pure Virtual Function in C++ krishna_sicsr Programming 1 06-03-2007 05:11 PM



All times are GMT -4. The time now is 08:05 AM.