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

R

Robert Bralic

#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);
}
 
M

Michael Karas

#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.
 
I

Ike Naar

#include<stdio.h>

Don't forget to #include <stdlib.h> for malloc() and atoi(),
and to #include said:
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 should return an int, but here you reach the closing
brace without returning a value. Did you mean

return chk(c);

?
 
B

Barry Schwarz

#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);
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top