Infix to reverse polish notation - c

I am writing a code to convert infix expression to reverse notation but my program is crashing on executing the file
typedef struct stack
{
char a[400];
int top;
}
stack;
stack s;
void push(char *,int);
int pop();
int main()
{
char x[400];
int len,i,y;
puts("Enter string");
scanf("%s",x);
len=strlen(x);
for(i=0;i<len;i++)
{
//considering user is entering only the small alphabets
if((x[i])>=97&&x[i]<=122)
printf("%s",x[i]);
else
//if encountering the operator then pushing it into stack
if(x[i]=='/'||x[i]=='*'||x[i]=='+'||x[i]=='-')
{
push(x,i);
}
else if(x[i]=='(')
continue;
//When encountering the ')' then popping the operator
else
{
y=pop();
printf("%c",y);
}
}
return 0;
}
Passing array and its size as argument
void push(char *x,int i)
{
stack s;
s.top++;
s.a[s.top]=x[i];
}
Returning the popped operator on finding out the ")"
int pop()
{
stack s;
int temp;
temp=s.a[s.top];
s.top--;
return temp;
}

In your code
printf("%s",x[i]);
is wrong. What you want is
printf("%c",x[i]);
AS per the C11 standard, chapter 7.21.6.1, %s format specifier
If no l length modifier is present, the argument shall be a pointer to the initial
element of an array of character type. ...
but here x[i] is of type char.
Also, from paragraph 9,
If any argument is
not the correct type for the corresponding conversion specification, the behavior is
undefined.
So, your code invokes undefined behaviour.
Next, for both the functions, push() and pop(), you're defining a local variable stack s; which is created on each call to those functions and destroyed upon finishing execution. You may want to use the gloabl variable instead. Remove the local variables, they are not needed.
Also, for both the functions, you're using s.top value as the index of s.a array but without any boundary check on the same. You should put a check on the array index value for stack full case (push()) and stack empty case (pop()) before using s.top value as index. The increment and decrement of the s.top should also be placed under the check.
EDIT:
For the logical part, after parsing all the inputs, you should chcek if there is any element left on the stack to be popped or not. You should print the stack containts untill the stack becomes empty to get the complete notation. Check my comment below for the idea of a pseudocode.
Note: As per C standard, int main() should be int main(void)

Related

Getting different output for the same program when compiled in Dev-c++ and gcc 4.8.2

#include<stdio.h>
#include<stdlib.h>
#define max 10
void init_graph(int arr[max][max],int v);
void create_graph(int arr[max][max],int v);
void print_graph(int arr[max][max],int v);
int main()
{
int v,n;
printf("Enter the number of vertices :");
scanf("%d",&v);
int arr[v][v];
init_graph(arr,v);
printf("v=%d after init\n",v);
create_graph(arr,v);
print_graph(arr,v);
return 0;
}
void create_graph(int arr[max][max],int v)
{
printf("v=%d \n",v);
int e;
printf("Enter the number of edges :");
scanf("%d",&e);
int i,src=0,dest=0;
for(i=0;i<e;i++)
{
printf("Enter Edge :%d",i+1);
scanf("%d %d",&src,&dest);
if(src<=-1 || src>=v)
{
printf("Invalid source vertex \n");
i--;
continue;
}
if(dest<=-1 || dest >=v)
{
printf("Invalid dest vertex \n");
i--;
continue;
}
//*(*(arr+src)+dest)=1;
//*(*(arr+dest)+src)=1;
arr[src][dest]=1;
arr[dest][src]=1;
}
}
void init_graph(int arr[max][max],int v)
{
int i,j;
for(i=0;i<v;i++)
{
for(j=0;j<v;j++)
{
//*(*(arr+i)+j)=0;
arr[i][j]=0;
}
}
printf("V=%d init_graph\n",v);
}
void print_graph(int arr[max][max],int v)
{
int i,j;
for(i=0;i<v;i++)
{
for(j=0;j<v;j++)
{
//printf("%d ",*(*(arr+i)+j));
printf("%d ",arr[i][j]);
}
printf("\n");
}
}
When I compiled the above program in Dev-c++ and in gcc 4.8.2 I'm getting different output. Here I'm trying to represent a graph using adjacency matrix representation.
when v is passed as parameter to the init_graph(arr,v)(in the above program), even though I'm not returning any value from the function, the value of v is becoming zero after after the function has been called.
It is working properly in Dev-c++ but I'm getting the wrong answer when compiled in gcc.4.8.2.
Screenshot of the output in Dev-c++
here v is not becoming 0
Screenshot of the output in gcc 4.8.2
and here v is becoming 0.
You are calling the function:
void init_graph(int arr[10][10], int v);
However your code is:
int arr[v][v];
init_graph(arr,v);
This causes undefined behaviour if v is not 10. The C11 standard clause is 6.5.2.2/6:
If [...] the types of the arguments after promotion are not compatible with the types of the parameters, the behavior is undefined.
Arrays of dimension X are only compatible with arrays of dimension Y if X == Y. (Bear in mind that the innermost dimension is "lost" due to the array as function parameter syntax quirk, so the innermost dimension can differ without breaking compatibility).
To fix this you should include the size in the array dimension in the function prototype:
void init_graph(int v, int arr[v][v]);
and similarly for the other functions.
Due to the way "array" function parameters are "adjusted" to pointers in C, the create_graph function really accepts a pointer to an array of length max. It is equivalent to this:
void create_graph(int (*arr)[max], int v)
That means that when you each iteration over arr[i] in the loop takes a step of size 10 ints, to the next length 10 array. But you are passing (after array decay) a pointer to an array of length v. If v is not the same as max, that is already undefined behaviour (UB). In your case, this takes you out of bounds, (that would cause UB by itself in an otherwise well defined program.)
You can only call the function with a pointer to array of length max or with an array of arrays whose inner array length is max (the latter will decay to pointer to array.)
Note that the type of platform dependent behaviour you saw is often a sign thet there is UB in the code.
In main() you define your array to be of size [v][v], but init_graph() takes an array of size [max][max]. You need to make these the same. I suggest changing main() since all your other functions also use max as the array size.
What happens is that when v is 5, your [5][5] array is laid out as 25 consecutive ints. But the function thinks the array is size [][10], with row size of 10 ints. So the moment you write to any element past [2][4] (the 25th element), you are writing past the end of the array and clobbering your stack. This is because your array in main() was defined as a local variable and is therefore located on the stack. In your case, the stack also contained the value of v, and it got overwritten with a 0. The reason the other compiler worked is probably because it located v before the array in memory instead of after it, so with that compiler it didn't happen to clobber v.
According to the other answers, calling the function with an incorrect argument invokes "undefined behavior" but I find that to be a lazy explanation ("anything can happen"). I hate it when people say that because any compiled program is a known quantity any you can determine exactly what the "undefined" behavior actually is (just step through it with a debugger). Once you learn what is going on and where your variables are located, you will start to intuitively understand when memory is getting corrupted and what code could possibly be responsible for it.

What is the difference between two sets of code writen below

#include<stdio.h>
int *fun();
main()
{
int *i;
i=fun();
printf("cbgg\n");
printf("%d",*i);
getch();
}
int *fun()
{
int k;
k=5;
return (&k);
}
Though the program written above prints a garbage value for i, yet the the program written below works fine,i.e. the output is absolutely relevant, which is 5. Why is this so?
#include<stdio.h>
int inc();
main()
{
int i;
i=inc();
printf(“cbgg\n”);
printf(“%d”,i);
getch();
}
int inc()
{
int k;
k=5;
return (k);
}
The main difference is that this one does a pretty nasty thing by returning the address of a local variable (allocated on the stack) - Later usage of the returned pointer calls for undefined behavior.
int *fun()
{
int k;
k=5;
return (&k);
}
The other one is just a harmless return of 5 from the fun() routine.
To understand this you need to know a little bit about how arguments are passed to and from functions. When "fun" is called the arguments to "fun" are pushed on the stack (among other things). For "fun" to return values it pushes them on the stack and the caller later pops the value.
The local variable int k has function scope so when the function "fun" exits the stack space used is destroyed. Returning a pointer to that destroyed memory area is undefined behavior and that is what you are doing when you return &k. In #2 you instead push the value of k on the stack and that is valid.
In first case you are returning pointer to local variable,whose scope is limited to function only.
Whenever you return from function stack gets modified and you get unexpected data.

What are Function Pointers?

What are Function Pointers in plain English?
In simple english,
A FUNCTION_POINTER is a pointer which points towards the address of
fuction's first instruction, like a POINTER which points towards the
address of a variable.
Take a example of a program to understand the concept
Sum of all integers upto the user i/p
-
#include <stdio.h>
int IsAny(long n)
{
return 1;
}
long AddIf(long limit, int (*funPointer)(long))
{
long sum = 0;
register int i;
for(i = 1; i <= limit; ++i)
{
if(funPointer(i))
sum += i;
}
return sum;
}
int main(void)
{
long l, total;
printf("Enter a positive integer: ");
scanf("%ld", &l);
total = AddIf(l, IsAny);
printf("Sum of all integers upto %ld is %ld\n", l, total);
}
Here FUNCTION_POINTER is called to call IsAny function in AddIf with a declaration
as int (*funPointer)(long)) in AddIf function
As you asked in plain english, let's give it a try.
A pointer is an address in memory. A pointer has a type so the program can "find" the object you are refering to when using your pointer.
A function pointer uses the same logic. It declares a function that will be used has a method parameter for exemple. So you know that you will use a function that will have an input and an ouput in that method but the logic in that function don't need to be known.
From there you can send any function pointer to be used as the program only concern is that you will send and receive predefined types.
According wiki
A function pointer (or subroutine pointer or procedure pointer) is a type of pointer supported by third-generation programming languages (such as PL/I, COBOL, Fortran,1 dBASE dBL, and C) and object-oriented programming languages (such as C++ and D).2 Instead of referring to data values, a function pointer points to executable code within memory. When dereferenced, a function pointer can be used to invoke the function it points to and pass it arguments just like a normal function call. Such an invocation is also known as an "indirect" call, because the function is being invoked indirectly through a variable instead of directly through a fixed name or address. Function pointers can be used to simplify code by providing a simple way to select a function to execute based on run-time values.
Pointer = That hold the address of a variable or means simple memory.
As same like pointer , function pointer that hold the address of a function.
Syntax :
return type (*fp) (argument);
Example:
void f1()
{
printf("in function f1");
}
int main()
{
/* declaring a function pointer
* argument void
* return type is also void
*/
void (*fun_ptr) (void);
fun_pt= f1(); // fun_pthold the address of f1
(*fun_pt)(); // calling a function f1
}

"Pointer Expected" and "Conflicting argument type" error in C

So, I have written a function for insertion into a queue viz en_queue. The function body is:
void en_queue(queue,max,front,rear)
{
int ch1;
printf("\n Enter element to add->");
scanf("%d",&ch1);
if(front==0 && rear==(max-1))
{
printf("\n Caution!! Queue Overflow!!");
}
else if(rear==(max-1) && front>0)
{
rear=0;
*queue[rear]=ch1;
}
else if(front==-1 && rear==-1)
{
front=rear=0;
*queue[rear]=0;
}
else
{
rear++;
*queue[rear]=ch1;
}
}
And the prototype declaration is:
void en_queue(int *,int, int, int);
And during calling, I called it like:
en_queue(queue,MAX,front,rear);
where queue[MAX] is an array (#define MAX 10), MAX is the number of elements the array can incorporate and both front and rear are integers with current value -1. I am getting repeated errors of type error: pointer expected and Conflicting argument declarations for function 'en_queue'.
I can't see why arguments are not matching. Because I passed an address of the array and received it in a pointer variable and worked with the pointer. So how can there be error?
First:
void en_queue(queue,max,front,rear)
{
should be:
void en_queue(int *queue, int max, int front, int rear)
{
And second, expressions like *queue[rear] = 0; should be just queue[rear] = 0; because queue is int*.
Note: An expression a[i] == *(a + i), so if a is pointer then in expression a[i] you doesn't need to deference * explicitly.
In your expression *queue[rear], you are getting error type error: pointer expected because you dereference twice e.g. *queue[rear] == * *(queue + rear) because *(queue + rear) is not pointer but a int hence compiler message is need a pointer.
Compiler message: "Conflicting argument declarations for function en_queue()" because of first argument is int*. As in function definition you doesn't specify type of arguments default is considered int type.
If queue is int * then the correct way to access it as an "array" is
queue[index];
and NOT *queue[index]
queue[index] is actually *(queue + index).
if you do *queue[index] you are actually doing *(*(queue + index)) .
(queue + index) will get to the address location index locations away from the addres stored in queue . *(queue + index) will dereference it by getting the value stored at the address. *(*(queue + index)) will use the fetched value as an address and try to make another fetch, which is wrong because now you dereference an integer.
While you can write a declaration without naming your arguments, just giving the type specifiers, you cannot write a definition with only the names and without the specifiers. The conflicting argument declarations error is because of this, because the compiler interprets the argument names in your definition as types rather than names. Think about it, how could the compiler know the difference between a name given without a type and a type given without a name?
As #grijesh has written, you should write your definition as:
void en_queue(int *queue, int max, int front, int rear)
instead.
The other problem is that you're dereferencing your pointer twice, which doesn't make sense with a pointer to an integer. An array and a pointer are similar in the way that they give a memory address that you can use to do further indexing. This can be done by using the regular index operator:
queue[index]
or using the explicit pointer dereferencing operator *, and pointer arithmetic like this:
*(queue + index)
Read more about pointer arithmetic here.
You said: ..where queue[MAX] is an array..
Your declaration is: void en_queue(int *,int, int, int);
Then what does this mean: *queue[rear]=ch1;
You are trying to dereference an integer
Correct all the instances in your program like above to: queue[rear] = ch1;

C Function implementation - with Pointer vs without Pointer

I've just started to work with C, and never had to deal with pointers in previous languages I used, so I was wondering what method is better if just modifying a string.
pointerstring vs normal.
Also if you want to provide more information about when to use pointers that would be great. I was shocked when I found out that the function "normal" would even modify the string passed, and update in the main function without a return value.
#include <stdio.h>
void pointerstring(char *s);
void normal(char s[]);
int main() {
char string[20];
pointerstring(string);
printf("\nPointer: %s\n",string);
normal(string);
printf("Normal: %s\n",string);
}
void pointerstring(char *s) {
sprintf(s,"Hello");
}
void normal(char s[]) {
sprintf(s,"World");
}
Output:
Pointer: Hello
Normal: World
In a function declaration, char [] and char * are equivalent. Function parameters with outer-level array type are transformed to the equivalent pointer type; this affects calling code and the function body itself.
Because of this, it's better to use the char * syntax as otherwise you could be confused and attempt e.g. to take the sizeof of an outer-level fixed-length array type parameter:
void foo(char s[10]) {
printf("%z\n", sizeof(s)); // prints 4 (or 8), not 10
}
When you pass a parameter declared as a pointer to a function (and the pointer parameter is not declared const), you are explicitly giving the function permission to modify the object or array the pointer points to.
One of the problems in C is that arrays are second-class citizens. In almost all useful circumstances, among them when passing them to a function, arrays decay to pointers (thereby losing their size information).
Therefore, it makes no difference whether you take an array as T* arg or T arg[] — the latter is a mere synonym for the former. Both are pointers to the first character of the string variable defined in main(), so both have access to the original data and can modify it.
Note: C always passes arguments per copy. This is also true in this case. However, when you pass a pointer (or an array decaying to a pointer), what is copied is the address, so that the object referred to is accessible through two different copies of its address.
With pointer Vs Without pointer
1) We can directly pass a local variable reference(address) to the new function to process and update the values, instead of sending the values to the function and returning the values from the function.
With pointers
...
int a = 10;
func(&a);
...
void func(int *x);
{
//do something with the value *x(10)
*x = 5;
}
Without pointers
...
int a = 10;
a = func(a);
...
int func(int x);
{
//do something with the value x(10)
x = 5;
return x;
}
2) Global or static variable has life time scope and local variable has scope only to a function. If we want to create a user defined scope variable means pointer is requried. That means if we want to create a variable which should have scope in some n number of functions means, create a dynamic memory for that variable in first function and pass it to all the function, finally free the memory in nth function.
3) If we want to keep member function also in sturucture along with member variables then we can go for function pointers.
struct data;
struct data
{
int no1, no2, ans;
void (*pfAdd)(struct data*);
void (*pfSub)(struct data*);
void (*pfMul)(struct data*);
void (*pfDiv)(struct data*);
};
void add(struct data* x)
{
x.ans = x.no1, x.no2;
}
...
struct data a;
a.no1 = 10;
a.no1 = 5;
a.pfAdd = add;
...
a.pfAdd(&a);
printf("Addition is %d\n", a.ans);
...
4) Consider a structure data which size s is very big. If we want to send a variable of this structure to another function better to send as reference. Because this will reduce the activation record(in stack) size created for the new function.
With Pointers - It will requires only 4bytes (in 32 bit m/c) or 8 bytes (in 64 bit m/c) in activation record(in stack) of function func
...
struct data a;
func(&a);
...
Without Pointers - It will requires s bytes in activation record(in stack) of function func. Conside the s is sizeof(struct data) which is very big value.
...
struct data a;
func(a);
...
5) We can change a value of a constant variable with pointers.
...
const int a = 10;
int *p = NULL;
p = (int *)&a;
*p = 5;
printf("%d", a); //This will print 5
...
in addition to the other answers, my comment about "string"-manipulating functions (string = zero terminated char array): always return the string parameter as a return value.
So you can use the function procedural or functional, like in printf("Dear %s, ", normal(buf));

Resources