How to make this work with pointer inside main...

Discussion in 'C Programming' started by Robert Bralic, Dec 27, 2011.

  1. #include<stdio.h>


    int *p;

    int main(int argc, char *argv[]){
    int i, j, k, n, m;
    if(!chk(argv[1])||!chk(argv[2])){
    printf ("\nUsage p number_1 number_2");
    return 1;
    }
    m=atoi(argv[1]);
    n=atoi(argv[2]);
    p=(int*)malloc(sizeof(int)*n);
    printf("\n==========================================\n");
    write(m, m, n);
    printf("\n==========================================\n");
    p--;
    write_reverse(n);
    printf("\n==========================================\n");
    return 0;
    }


    write(int i, int m,int n){
    if(n==0)return 0;
    *p=i;
    n--;
    i=i*m;
    printf("%d ", *p);
    p++;
    write(i,m , n);
    }

    write_reverse(int n){
    if(n==0)return 0;
    printf("%d ", *p);
    n--;
    p--;
    write_reverse(n);
    }


    int chk(char *c){
    if(!isdigit(*c) && *c!='\0') return 0;
    if(*c=='\0') return 1;
    *c++;
    chk(c);
    }
    Robert Bralic, Dec 27, 2011
    #1
    1. Advertising

  2. In article <jdbrjd$q24$-com.hr>, -com.hr
    says...
    >
    > #include<stdio.h>
    >
    >
    > int *p;
    >
    > int main(int argc, char *argv[]){
    > int i, j, k, n, m;
    > if(!chk(argv[1])||!chk(argv[2])){
    > printf ("\nUsage p number_1 number_2");
    > return 1;
    > }
    > m=atoi(argv[1]);
    > n=atoi(argv[2]);
    > p=(int*)malloc(sizeof(int)*n);
    > printf("\n==========================================\n");
    > write(m, m, n);
    > printf("\n==========================================\n");
    > p--;
    > write_reverse(n);
    > printf("\n==========================================\n");
    > return 0;
    > }
    >
    >
    > write(int i, int m,int n){
    > if(n==0)return 0;
    > *p=i;
    > n--;
    > i=i*m;
    > printf("%d ", *p);
    > p++;
    > write(i,m , n);
    > }
    >
    > write_reverse(int n){
    > if(n==0)return 0;
    > printf("%d ", *p);
    > n--;
    > p--;
    > write_reverse(n);
    > }
    >
    >
    > int chk(char *c){
    > if(!isdigit(*c) && *c!='\0') return 0;
    > if(*c=='\0') return 1;
    > *c++;
    > chk(c);
    > }


    1) Provide the proper prototypes for the subroutines at the top of the
    file.

    2) Declare p inside of main()

    3) Add an argument to each of write() and write_reverse() that is a
    pointer to a pointer.

    4) Call each of the modified write() and write_reverse() functions with
    &p in the argument position as added in 3) above.

    5) In each of the subroutines that accept this pointer to pointer
    argument you'll have to either re-write the code to properly dereference
    the passed argument OR add a local pointer that you set to the value of
    the dereferenced entry argument.

    --

    Michael Karas
    Carousel Design Solutions
    http://www.carousel-design.com
    Michael Karas, Dec 27, 2011
    #2
    1. Advertising

  3. Robert Bralic

    Ike Naar Guest

    On 2011-12-27, Robert Bralic <-com.hr> wrote:
    > #include<stdio.h>


    Don't forget to #include <stdlib.h> for malloc() and atoi(),
    and to #include <ctype.h> for isdigit().

    > int *p;
    >
    > int main(int argc, char *argv[]){
    > int i, j, k, n, m;


    What is the purpose of i, j and k?

    > if(!chk(argv[1])||!chk(argv[2])){


    This is not safe. If argc equals 0, argv[1] and argv[2]
    may not exist.

    > printf ("\nUsage p number_1 number_2");


    Why is there a newline at the beginning?
    Why is there no newline at the end? This may lead to
    problems on platforms that require the last output line
    to be newline-terminated.

    > return 1;


    Although this will work on many platforms, returning
    EXIT_FAILURE is a) more portable, and b) clearer.

    > }
    > m=atoi(argv[1]);
    > n=atoi(argv[2]);


    Keep in mind that atoi does not check the validity of
    its input string, if the input string is not a valid
    integer atoi simply returns 0, so you cannot distinguish
    between the input strings "0" and "bzzt".

    > p=(int*)malloc(sizeof(int)*n);


    The cast is unnecessary.
    malloc can return a null pointer; you should check for this.
    The allocated memory is never freed.

    > printf("\n==========================================\n");
    > write(m, m, n);


    It's better to have a declaration of write() appear before
    callint write(). So, either move the definition of ``write''
    before main(), or at least add a forward declaration before main.

    > printf("\n==========================================\n");
    > p--;
    > write_reverse(n);


    Same as above, calling write_reverse() without having seen
    a declaration.

    > printf("\n==========================================\n");
    > return 0;
    > }
    >
    >
    > write(int i, int m,int n){


    You need to decide whether you want this function to
    return a value, and then write the declaration properly.
    As it is now, the function returns 0 if n==0, and returns
    no value otherwise. In any case, the returned value is never
    used. Assuming the function does not need to return a value,
    make the prototype:

    void write(int i, int m, int n)

    > if(n==0)return 0;


    and then change the line above to

    if (n==0) return;

    > *p=i;
    > n--;
    > i=i*m;
    > printf("%d ", *p);
    > p++;
    > write(i,m , n);
    > }
    >
    > write_reverse(int n){


    Same as above:

    void write_reverse(int n)

    > if(n==0)return 0;


    if (n==0) return;

    > printf("%d ", *p);
    > n--;
    > p--;
    > write_reverse(n);
    > }
    >
    >
    > int chk(char *c){
    > if(!isdigit(*c) && *c!='\0') return 0;
    > if(*c=='\0') return 1;
    > *c++;


    What is the purpose of this statement?
    As it is written, c in incremented, and the old value of c
    dereferenced, but the dereferenced value is never used, so
    the statement is equivalent to c++;
    If the intention was to increment the value pointed at by c,
    then write (*c)++ or ++(*c) or ++*c;

    > chk(c);


    chk should return an int, but here you reach the closing
    brace without returning a value. Did you mean

    return chk(c);

    ?

    > }
    >
    >
    >
    Ike Naar, Dec 27, 2011
    #3
  4. On Tue, 27 Dec 2011 08:20:13 +0100, "Robert Bralic"
    <-com.hr> wrote:

    >#include<stdio.h>
    >
    >
    >int *p;
    >
    >int main(int argc, char *argv[]){
    > int i, j, k, n, m;
    > if(!chk(argv[1])||!chk(argv[2])){


    A little horizontal spacing would go a long way toward making your
    code readable.

    You should check that argc is at least 3 before evaluating any
    argv[x].

    > printf ("\nUsage p number_1 number_2");
    > return 1;


    Using EXIT_FAILURE would make this portable so others can test your
    code.

    > }
    > m=atoi(argv[1]);


    atoi will not tell you if there was any problem converting the string
    to an integer. Consider using strtol.

    > n=atoi(argv[2]);
    > p=(int*)malloc(sizeof(int)*n);


    The cast is unnecessary and in this case it masks undefined behavior.
    You probably added it to silence the diagnostic about converting the
    return value of malloc to a pointer. However, the correct approach to
    that warning is to #include stdlib.h. The absence of a prototype for
    malloc causes the compiler to assume it returns an int which is
    definitely not the case.

    If you use sizeof(*p), parentheses optional, instead of sizeof(int),
    the code will "self-adjust" if you ever change the type of p.

    > printf("\n==========================================\n");
    > write(m, m, n);


    Functions should either be defined or have a prototype in scope before
    they are called..

    > printf("\n==========================================\n");
    > p--;
    > write_reverse(n);
    > printf("\n==========================================\n");
    > return 0;
    >}
    >
    >
    >write(int i, int m,int n){


    The use of an implied return type of int has been deleted from the C
    language.

    Did you really mean for write to return an int?

    > if(n==0)return 0;
    > *p=i;
    > n--;
    > i=i*m;
    > printf("%d ", *p);
    > p++;
    > write(i,m , n);
    >}
    >
    >write_reverse(int n){
    > if(n==0)return 0;
    > printf("%d ", *p);
    > n--;
    > p--;
    > write_reverse(n);
    >}
    >
    >
    >int chk(char *c){
    > if(!isdigit(*c) && *c!='\0') return 0;
    > if(*c=='\0') return 1;
    > *c++;
    > chk(c);
    >}


    Let's assume that on the initial call to this function, c points to
    "5a". For recursion level 1:
    *c is '5'.
    The first if is false.
    The second if is false.
    c is incremented.
    Recursion level 2 is entered.
    *c is 'a'.
    The first if is true.
    Return to level 1 with a value of 0.
    The return value is discarded.
    The function returns to main with no return value. This is
    undefined behavior. Who knows what value main sees.

    There is no need for this function to be recursive. A loop would work
    at least as well. If you really want it to be recursive, change the
    last statement to
    return chk(c);

    --
    Remove del for email
    Barry Schwarz, Dec 27, 2011
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. John M
    Replies:
    1
    Views:
    1,133
    Kumar Reddi
    May 29, 2005
  2. Hal Styli
    Replies:
    14
    Views:
    1,629
    Old Wolf
    Jan 20, 2004
  3. Frederick Ding

    int main() or int main(void)?

    Frederick Ding, Dec 3, 2005, in forum: C Programming
    Replies:
    10
    Views:
    651
  4. main() called inside main()

    , May 4, 2006, in forum: C Programming
    Replies:
    14
    Views:
    1,425
    Richard Heathfield
    May 7, 2006
  5. Immortal Nephi
    Replies:
    0
    Views:
    247
    Immortal Nephi
    Feb 22, 2009
Loading...

Share This Page