Why do we initialize top of the stack as -1? - c

Why do I have to initialize one of the stacks to -1? Where would top1 point to?
int ar[SIZE];
int top1 = -1;
int top2 = SIZE;
void push_stack1 (int data)
{
if (top1 < top2 - 1)
{
ar[++top1] = data;
}
else
{
printf ("Stack Full! Cannot Push\n");
}
}

The difference is whether you let top1 point to the last used element or the first free element.
With -1 you let it point to the last used element.
With 0 you let it point to the first free element.
There is also symmetry in the use of pre-increment/decrement and post-increment/decrement.
Initializing to -1 implies ++top1 for push and top1-- for pop.
Initializing to 0 implies top1++ for push and --top1 for pop.

No, you wouldn't have to initialize top1 as -1 at all if your code would have been:
int ar[SIZE];
int top1 = 0; // 0 `here`
int top2 = SIZE;
void push_stack1 (int data)
{
// v conditional check with `<=` instead of `<`
if (top1 <= top2 - 1) // even better: `if (top1 < top2)`
{
ar[top1++] = data;
// ^ using "top1++" instead of "++top1"
}
else
{
printf ("Stack Full! Cannot Push\n");
}
}
++something (also known as pre-increment) will increment the value of something, and then return the incremented value.
Whereas, something++ (also known as post-increment) will increment the value of something, but return the original value that something held before being incremented.
But you must note here that whether it is ++top1 or top1++, we are always passing 0 as the first index to ar because the 0 is the first index of any array/list in all the languages.

This is really odd that you started to think that in stack datastructure's implementation - you would have to initialize top with -1. Whick book said that? If any book did, at it's best it can mostly mean that the implementation they showed is following that.
Where would top1 point to? If you directly index into an array object, then yes it would likely try to access a memory which is out of the array bound, which is surely an undefined behavior(Arrays are 0-indexed in C ). But in every scenarios, we see implementation where top is increased first (in case top is initialized with -1)++top and then that value is used to index into array (For the very first time this will result in 0), which is precisely the case here. (Array is mentioned here because it seems that underlying data structure the code you showed uses that).
So top=-1 will initially mean that it is in a empty state and you can say no member is being added to the stack data structure. Here you could have initialized top with 0 also provided that you would have to change your push,pop or isEmpty() and other auxiliary functions associated with this data structure implementation accordingly, as needed.
Also you can check your other function's implementation to get the justification of top=-1 for the implementation with which you are working on.
Also if you are in doubt about what ++ does here and how is it significant - Look what C11 standard has to say about it (N1570Draft)
In section §6.5.3.1¶2
The value of the operand of the prefix ++ operator is incremented. The result is the new value of the operand after incrementation.
++top1 will result in the new incremented value which is 0 in case it was -1 earlier.

Related

I'm am trying to check to see if a variable is empty or not in C

I have a variable that is going to store a -1 and if not a -1 then a 1, but before I store the 1 I want to check the variable for NaN. For example:
#include <stdio.h>
int main( void )
{
int someVar;
if (some condition)
someVar = -1;
else if((someVar == NaN) && (some other condition))
someVar = 1;
return 0;
}
Will the first condition return true in the else if statement if there is nothing stored in someVar?
A variable cannot be "empty." It always has a value.
You can manually specify a value, which indicates "emptiness" as done with strings: a null byte (with the value 0) indicates the end of the string. Here, it's not emptiness per se but you get what I mean, hopefully.
Because a variable cannot be empty, there is no common NaN value for it; every value is a number, so NaN (not a number) does not make sense.
The floating-point format IEEE 754 supports NaN values but that is only possible because certain values of floating-point numbers have been assigned that meaning.
A variable resides in RAM. RAM is never empty. Each cell has a value. Either the value is known by the programmer or not, depends whether the programmer has initialized that variable or not.
I know two ways of signaling the "emptyness" of a variable. One is to have a value that means "empty", like "0", or MAX_INTEGER, or whatever you like. This works if the logic of your algorithm imposes your variable to have only certain values, so you can know when the value is valid or not. If not, you can say the variable is not valid, or empty.
If your variable can hold any value (within the limits of your type), then a solution may be to use a small struct, like this:
typedef struct
{
int value;
int is_empty;
} tVar;
So declaring variable i this way...
tVar i;
You can initialize as empty, like this:
i.is_empty = 1;
So, your program becomes:
int main( void )
{
tVar someVar = {0,1}; // declaring and initializing it as empty
...
...
...
if (!someVar.is_empty) // if someVar is not empty...
{
someVar.value = -1;
someVar.is_empty = 0; // is not empty any more
}
else if (someVar.is_empty && (some_other_condition))
{
someVar.value = 1;
someVar.is_empty = 0;
}
return 0;
}
You can't have "nothing" stored in variable. Every variable has value.
In most cases there will be stored "0", but in not-so-rare cases you will have some garbage stored in your Variable. Its something that's just left there just before your Variable got it's place in memory (the one where 'garbage' is).
The 'NaN' you get in some other cases, like dividing by zero, and something like that.
You always have a value to a variable. If you didn't store anything in it, It stores a random number which often called "Garbage", and we want to avoid it. So you can't check if a variable is empty, because it never will be.

Does C99 Standard allow the compiler to transform code such that the same expression is no longer evaluated once some deduced condition is met?

I don't quite get the following part of 5.1.2.3/3:
An actual implementation need not evaluate part of an expression if it can deduce that its
value is not used and that no needed side effects are produced (including any caused by
calling a function or accessing a volatile object).
Suppose I have the following code:
char data[size];
int i;
int found;
/* initialize data to some values in here */
found = 0;
for( i = 0; i < size; i++ ) {
if( data[i] == 0 ) {
found = 1;
/* no break in here */
}
}
/* i no longer used, do something with "found" here */
Note that found starts with 0 and can either remain unchanged or turn into 1. It cannot turn into 1 and then into something else. So the following code would yield the same result (except for i value which is not used after the loop anyway):
char data[size];
int i;
int found;
/* initialize data to some values in here */
found = 0;
for( i = 0; i < size; i++ ) {
if( data[i] == 0 ) {
found = 1;
break;
}
}
/* i no longer used, do something with "found" here */
Now what does the Standard say about need not evaluate part of an expression with regard to found = 1 and the loop control expressions which follow the first iteration in which control gets inside if?
Clearly if found is used somewhere after this code the compiler must emit the code that traverses the array and conditionally evaluates found = 1 expression.
Is the implementation required to evaluate found = 1 once for every zero found in the array or can it instead evaluate it no more that once and so effectively emit the code for the second snippet when compiling the first snippet?
can it instead evaluate it no more that once and so effectively emit the code for the second snippet when compiling the first snippet?
Yes, a compiler has the right to perform that optimization. It seems like a pretty aggressive optimization but it would be legal.
It might be interesting to look at an example that more closely matches the spirit of the text:
An actual implementation need not evaluate part of an expression if it can deduce that its value is not used and that no needed side effects are produced (including any caused by calling a function or accessing a volatile object).
Suppose we have:
int x = pureFunction(y) * otherPureFunction(z);
Suppose the compiler knows that both functions are int-returning "pure" functions; that is, they have no side effects and their result depends solely on the arguments. Suppose the compiler also believes that otherPureFunction is an extremely expensive operation. A compiler could choose to implement the code as though you had written:
int temp = pureFunction(y);
int x = temp == 0 ? 0 : temp * otherPureFunction(z);
That is, determine that under some conditions it is unnecessary to compute otherPureFunction() because the result of the multiplication is already known once the left operand is known to be zero. No needed side effects will be elided because there are no side effects.
Yes, it may perform this optimization, since there are no I/O operations, reads from volatile locations or externally visible writes to memory omitted by the optimized code, so the behavior is preserved.
As an example of this kind of optimization, GCC will compile
void noop(const char *s)
{
for (size_t i = 0; i < strlen(s); i++) {
}
}
to a completely empty function:
noop:
.LFB33:
.cfi_startproc
rep ret
.cfi_endproc
It is allowed to do so because the Standard guarantees the behavior of strlen, the compiler knows that it has no externally visible effect on s or any other piece of memory, and it can deduce that the whole function has no behavior. (Amazingly, this simple optimization brings the complexity down from quadratic to constant.)

C pointer sum "not working"

I do not understand what is the point in the else sentence *nombre=(*nombre)++.
Output shows "fernando" and what i thought it was going to show was "ffsoboep" because of the sum. But it seems that *nombre=(*nombre)+1 is different to *nombre=(*nombre)++;
My question is why is that happening? how does "++" operator works in that case. Thanks.
void recursiva (char * nombre)
{
if (*nombre != '\0')
{
recursiva(nombre+1);
if(*nombre > 'A' && *nombre < 'Z')
{
*nombre=*nombre | 32;
}
else
{
*nombre=(*nombre)++;
printf("%c \n",*nombre);
}
}
}
int main()
{
char nombre[]="Fernando";
recursiva(nombre);
printf("%s",nombre);
}
(*nombre)++
doesn't mean the same thing as
*nombre + 1
It means "return the original value of *nombre, with the side effect of increasing *nombre's value by 1". Note that when exactly the value of *nombre increases is rather vague; while it happens after the value of (*nombre)++ is computed, it might happen before, after, or during the assignment to *nombre, with unpredictable results.
If you want to increase the value of *nombre, you don't need to assign the value of (*nombre)++ back to *nombre, and in fact, trying to do so is undefined behavior. As a first approximation, the program is allowed to do anything, up to and including making demons fly out your nose. Just use ++:
(*nombre)++;
or += 1:
*nombre += 1;
I ran your code and actually got "ffsoboep".
If you see that in other compilers you get "fernando", I believe that the following point is not defined in the standard:
*nombre=(*nombre)++;
This is post increment. The value of (x++) is the value of x before the increment (i.e., x == x++ is true).
The question is when does the increment is done.
If the increment is done immediately or after the evaluation of the right side of the = expression, then you first increment the value, and then re-assign the value of the expression (*nombre)++ (which is the value before the increment) to the already incremented *nombre.
If the increment is done, after all the expression is evaluated, then you first assign the (same) value to *nombre, and only then increment.
I think this is not defined in the standard, and therefore - you might see different behaviours. I encountered similar case in the past.

Why does this recursive function loop infinitely rather than printing numbers in reverse?

int reverse(int);
void main()
{
int no =5;
reverse(no);
}
int reverse(int no)
{
if(no == 0)
return 0;
else
printf("%d",no);
reverse(no--);
}
This program goes in infinite loop.Why is that so? I am not able to get the desired ouput.
Desired output should be 5 4 3 2 1.Thank you in advance
In this recursive call:
reverse(no--);
You are passing the value of no--. Since this uses the postfix -- operator, this means "decrement no, then pass the original value of no into the recursive call to reverse." This causes infinite recursion, since you are constantly making a recursive call with reverse set to the same value.
To fix this, change this to read
reverse(no - 1);
Notice that there's no reason to decrement no here, since within the current recursive call you will never read no again. You can just pass the value of no - 1 into the function. In fact, you might want to in general avoid using -- in recursive calls, since it almost always indicates an error in the code.
Hope this helps!
You're using the post-decrement operator on no. That first gets the value of no and uses that as the value of the expression and then decrements no (still using the undecremented value as the value of the expression). You probably want to use --no or even just no - 1. (The former will modify no, whereas the latter will not, but it does not matter because no is not referenced after that point.)
Change:
reverse(no--);
to:
reverse(no-1);
no-- returns the original value before the decrement occurred. So this line will always call reverse(5). Hence, infinite loop.
n-- is post increment which first use n as argument of the function and then decrement n.
So n-- essentially does is
reverse(n);
n = n - 1;
What you want is --n
You are using post-decrement. First evaluates, then reduces value.
Change this:
reverse(no--);
to this:
return reverse(--no);
--no is pre-decrement. First decrease "no", then pass the value to reverse.
Note that I'm RETURNING the result value, you function always have to return an int, due to its declaration.
You want to do
int reverse(int);
int main()
{
int no =5;
reverse(no);
}
int reverse(int no)
{
if(no == 0)
return 0;
else
printf("%d",no);
return reverse(--no);
}
So that you're returning a number every time you call reverse and you decrement no before you use it.

Does array[-1] give the last element in the array?

programming my arduino microcontroller board in C, I noticed a strange behaviour.
Because of an logic mistake in my program the controller accessed the -1th element of an integer array.
int array[5];
array[4] = 27;
// array[-1] gives 27 now.
Is it correct that I get the last element of an array by using -1 as the element selector?
No, accessing elements outside of the index range is undefined behavior. In your case, the element at the address just prior to the beginning of your array is set to 27.
Since accessing array elements in C is nothing more than doing "straight" pointer arithmetic, passing negative indexes is not disallowed. You could construct a legitimate use case where indexes are negative and positive:
int raw[21], *data = &raw[10];
for (int i = -10 ; i <= 10 ; i++) {
data[i] = i;
}
No; array[-1] will not access the last element. It's more likely that the memory location just before the array has 27 stored in it. Try this:
array[4] = 27;
array[-1] = 0;
Then test whether array[-1] == array[4]. They will not be equal (assuming your program doesn't crash when assigning to array[-1]).
Accessing arrays with index out of bounds does not always crash your program. If the memory accessed by -1 is under your program control than an undefined value will pop out (which was stored by some other data created by your program). In your case it is mere coincidence.
No, that is incorrect according to the Standard. Accessing an element outside the array invokes Undefined Behaviour.
Your implementation might (I doubt it!) provide that functionality; but you really should not rely on it.
Try this:
#include<stdio.h>
int main()
{
int raw[4], *data = &raw[2];
raw[0]=0;
raw[1]=1; // -1 index for data
raw[2]=2;
raw[3]=3;
for (int i = 0 ; i < 2 ; i++) {
printf("\nvalue =%d i=%d\n",data[i],i);
}
printf("\nIndex,[-1]=%d\n", data[-1]);
return 0;
}
EDIT: Conclusion is that -1 will access last memory location.
If you are referring to C (and you are), then no. If you try to access an array with a negative index, you will get an out of bounds exception. However, Lua implements this exact thing as a feature. If you access a Lua array with an index of -1, it will read the last element of the array. An index of -2 will read the second-to-last element, and so-on.
Side note: you can annoy your coworkers by writing this
foo = {1,2,3,4,5,6,7,8,9,0}
print(foo.length() * -1])
This prints 1. Annoying, isn't it.

Resources