I have following sample code where i used pre-decrement
void function(int c)
{
if(c == 0)
{
return;
}
else
{
cout << "DP" << c << endl;
function(--c);
cout << c << endl;
return;
}
}
This function give output for input 4 as :
DP3
DP2
DP1
DP0
0
1
2
3
But when i use post decrement
void function(int c)
{
if(c == 0)
{
return;
}
else
{
cout << "DP" << c << endl;
function(c--);
cout << c << endl;
return;
}
}
Output goes in infinite loop with DP4
Can you explain me in detail why this happens ?
This happens because function(c--) will be called with the same value of c and when it finishes c will be decremented. But as it is recursively called, hence it will be called with same value with no chance of return and eventually you will hit stack overflow error.
Assume this, int x = 1, y = 0; Now y = x++ will result y == 1 and x == 2. But if you do y = ++x , then bot x and y will be 2.
Because --c will return c-1,however c-- return c.So when you use function(c--) is equal to function(c);c = c-1;.c will never be 0.So the function won't stop.
To know the difference between --x and x-- you can try the following code:
int x = 5,y=5;
cout<<x--<<endl;
cout<<--y<<endl;
cout<<x<<" "<<y<<endl;
In case of post decrement value will be passed before decrement , always same value will be passed to function , it never come out .
function(c--), first it call function(c) later decrement c-- will happen .
Related
For clarification, let's consider the following program:
#include <iostream>
int main(void) {
short int i; // declaration
short int value;
short int sum;
i = value = sum = 0; // initialization
std::cout << "Enter a value: ";
std::cin >> value;
while (i != value) { // ### here's the confusion ###
sum += i;
i++;
}
std::cout << "Total sum: " << sum << std::endl;
return 0;
}
Look at the while (i != value), when this expression is given, the results shows Total sum: 45 whereas if we put while (i <= value), it shows Total sum: 55. (Input's given 10 for example)
Here, the confusion is, when should we use != and <= or >= operations in loops, any specific condition?
According to TutorialsPoint's Operators Reference
it tells that != (returns true used when two operands are unequal).
<= (returns true when used when we need to ensure if the first operand is lesser than or equal to second).
It was expected to get no difference in output, but something's misunderstood.
This while loop
while (i != value)
does not include the iteration when i is equal to value because in this case the condition i != value evaluates to false.
This while loop
while (i <= value)
includes the iteration when i is equal to value because in this case the condition i <= value evaluates to true.
In fact the first condition can be rewritten the following way (provided that initially i is less than value)
while ( i < value )
Now compare it with the condition in the second loop that in turn can be rewritten like
while ( i < value || i == value )
That is you have two different conditions.
With
while( i <= value)
the last iteration is with i == value. With
while ( i != value)
The body of the loop will not be executed when i == value. That is the reason you observe the difference.
This is a good chance to learn how to use a debugger. And/Or realize that your example is already too complicated to directly see what is going on. You would have spotted the difference more easily with
int i = 0;
int value = 5;
while ( i != value) {
std::cout << i << " ";
}
i = 0;
while ( i <= value) {
std::cout << i << " ";
}
I came accross this expression, and can't understand the meaning of line 3 in the following snippet:
int A=0, B=0;
std::cout << A << B << "\n"; // Prints 0, 0
A += B++ == 0; // how does this exp work exactly?
std::cout << A << B << "\n"; // Prints 1, 1
A adds B to it, and B is Post incremented by 1, what does the "==0" mean?
Edit:
Here's the actual code:
int lengthOfLongestSubstringKDistinct(string s, int k) {
int ctr[256] = {}, j = -1, distinct = 0, maxlen = 0;
for (int i=0; i<s.size(); ++i) {
distinct += ctr[s[i]]++ == 0; //
while (distinct > k)
distinct -= --ctr[s[++j]] == 0;
maxlen = max(maxlen, i - j);
}
return maxlen;
}
B++ == 0
This is a boolean expression resulting in true or false. In this case the result is true, true is then added to A. The value of true is 1 so the (rough) equivalent would be:
if(B == 0)
A += 1;
++B;
Note that this isn't particulary good or clear to read code and the person who wrote this should be thrown into the Gulags.
Lets break this expression into pieces: A += value, whereas value = B++ == 0. As later cout suggests, value == 1. Why is that? Here is why: value is result of comparison of B++ and 0, but ++ (increment) operation, when written after operand, is being processed after the comparison, i.e. if you write A += ++B == 0 the later cout should (and does) print 0, 1.
I am trying to efficiently deduct which conditions caused an if statement to be overlooked by the program without using a sequence of if statements to verify each variable's relative integrity individually.
Is this possible?
bool state = false;
int x = 0;
int y = 1;
int z = 3;
if(x == 0 && y == 1 && z == 2) {
// Do something...
state == true;
}
if(state == false) {
std::cout << "I did not execute the if statement because the following
conditions were not met: " << std::endl;
/*Find a way to make the program output that z != 3 stopped the
conditional from running without directly using if(z != 2)*/
}
You could introduce a counter as a "condition" between each of the conditions in the if to see when short-circuit evaluation of operator && prohibits execution of the latter conditions:
int nrOfConditionFailing = 1;
if(x == 0 &&
nrOfConditionFailing++ && y == 1 &&
nrOfConditionFailing++ && z == 2) {
state = true;
}
if (!state) {
cout << "failed due to condition nr " << nrOfConditionFailing << endl;
}
If you want to check all the conditions, you cannot do it in a single if-statement; Short-circuit evaluation of operator && will prevent the latter conditions to be even checked/evaluated if one of the former conditions evaluates to false.
However, you could do such a check as an expression that marks a bit in an unsigned int for each condition that is not met:
int x = 1;
int y = 1;
int z = 3;
unsigned int c1 = !(x == 0);
unsigned int c2 = !(y == 1);
unsigned int c3 = !(z == 2);
unsigned int failures =
(c1 << 0)
| (c2 << 1)
| (c3 << 2);
if (failures) {
for(int i=0; i<3; i++) {
if (failures & (1 << i)) {
cout << "condition " << (i+1) << " failed." << endl;
}
}
}
else {
cout << "no failures." << endl;
}
If this is something you want to display to the end user, and not just while debugging, as suggested in the comments, you can design a simple data structure for yourself. It would be a list / vector / array of entries, each of which contain a) a value to compare against, b) a value to test, and optionally c) a description of the test.
Then simply iterate the list, and check if equality holds for all of them. If not, you can stop the flow of the programme and print out the description.
To more directly answer your question: no, there is nothing in C++ that would allow you to examine the results of previous statements. The statements and operations you see in the source code get compiled and possibly won't even be trivially recognisable among the assembly instructions. Being able to check the results would mean the data has to be stored somewhere, which would be an incredible waste of memory and processing time. That is why you have to do this yourself.
Is this possible?
It is not possible in the way you were thinking about the problem. You can solve your problem instead by running each test individually, storing the result, and then identifying which of them were false:
std::vector<std::tuple<std::string,bool> > tests = {
{"x==0",x==0}, // test name as a string followed by the actual test
{"y==1",y==1},
{"z==2",z==2}
};
if(!all_of(tests.begin(),tests.end(),[](std::tuple<std::string,bool> &t) { return std::get<1>(t); }))
{
std::cout << "The following tests failed: ";
//remove all tests that passed
tests.erase(
std::remove_if(tests.begin(),tests.end(),[](std::tuple<std::string,bool> &t) { return std::get<1>(t); }),
tests.end());
//This will only print out the tests that failed
std::transform(tests.begin(),tests.end(),std::ostream_iterator<std::string>(std::cout, " "),[](std::tuple<std::string,bool> &t) { return std::get<0>(t); });
std::cout << std::endl;
} else {
//what to do if all tests were true
}
This will evaluate all tests (i.e., it won't use &&'s short-circuiting) and print all the ones that failed. You could likely wrap this into a class to make this more generalizable and user friendly.
The original code tests each variable individually. The && series is exactly equivalent to a series of if...else statements. There's nothing inefficient about one compared to the other, and there's nothing "clever" about using some tricky solution that achieves the same end result as straightforward code.
I might write:
char const *reason = nullptr;
if(x != 0)
reason = "x failed";
else if (y != 1)
reason = "y failed";
else if (z != 2 )
reason = "z failed";
if ( reason )
std::cout << reason << '\n';
else
{
// success code here...
}
I would typically do something like the following to determine if a series of validity checks worked and to mark which ones failed.
unsigned long ulFlags = 0;
int x = 0;
int y = 1;
int z = 3;
ulFlags |= (x == 0) : 0 ? 0x0001; // if bit set then condition failed.
ulFlags |= (y == 1) : 0 ? 0x0002; // if bit set then condition failed.
ulFlags |= (z == 2) : 0 ? 0x0004; // if bit set then condition failed.
if(ulFlags == 0) {
// Do something since all conditions are met and valid ...
} else {
std::cout << "I did not execute if statement because: " << std::hex << ulFlags << std::endl;
/* Find a way to make the program output that z != 3 stopped the
conditional from running without directly using if(z != 2) */
}
This is the same idea as some of the other answers, but with a template to simplify the syntax to use it. Stores all the individual checks in an std::array<bool, N> and one additional bool to be able to re-check the full statement without going through the individual results again.
No dynamic allocation is a plus as well.
#include <iostream>
#include <array>
#include <type_traits>
template <typename... N>
struct what_failed {
what_failed(N... n) : arr{n...}, status{(... && n)} {
static_assert(std::conjunction_v<std::is_same<N, bool>...>, "Only pass bools");
}
std::array<bool, sizeof...(N)> arr;
bool status;
operator bool() { return status; }
};
int main() {
auto check = what_failed(2 == 5, 2 < 5, 2 > 5, 1 == 1);
if (check)
std::cout << "Check: All true";
else {
std::cout << "Check: ";
for (auto c : check.arr)
std::cout << c << ' ';
}
return 0;
}
This requires c++17 due to fold expressions and template deduction in a constructor, but that can be worked around for c++11 with a couple of extra help-templates.
#include <iostream>
int counter = 0;
int f(){
return counter++;
}
int main(){
std::cout << f(); //output = 0
std::cout << f()+f(); // output = 1;
return 0;
}
This might be a silly question but why isn't f() equal to 1 instead of 0 in the first case?
I thought counter++ was the same as counter = counter + 1?
No. counter++ is closer to (counter = counter + 1) - 1
Its because of the difference between postfix and prefix notation. In postfix notation which is what you have currently it saves a copy of the variable and then increments the variable for any calls below the current call however at the current call it will appear to stay the same.
This is why when we have std::cout << f(); //output = 0 it outputs 0 because counter will only increment after this line. If you change f to:
int f() { return ++counter; }
You will see the result you expected.
first, Are you sure f() + f() results in 1. I think it should be 3.
Regarding your main question:
post increment works on a copy of the original value. so your function in f() is acting as:
int f()
{
int temp = counter;
counter = counter + 1;
return temp;
}
or as cleverly noted by #kmkaplan:
int f()
{
return (counter = counter + 1 ) - 1;
}
it is similar to the semantic of:
int f = 0;
cout << f++; // f original value is first displayed.
cout << ++f; // f is incremented then displayed.
In general, I prefer to use ++n over n++ unless the program logic requires the opposite.
I was going over the C++ FAQ Lite online. I was browsing inlines again since I haven't found a use for them and wanted to know how the stopped the circular dependency as showed in this answer. I first tried to do the, "Why inlines are better than defines." example with the following code:
#define unsafe(i) \
( (i) >= 0 ? (i) : -(i) )
inline
int safe(int i)
{
return i >= 0 ? i : -(i);
}
int f();
int main(void)
{
int x(5);
int ans;
ans = unsafe(x++);
cout << ans << endl;
ans = unsafe(++x);
cout << ans << endl;
ans = safe(x++);
cout << ans << endl;
ans = safe(++x);
cout << ans << endl;
std::cin.get();
return 0;
}
EDIT:
Great. Got the typo out of the way. Not that I'm bitter that I don't find such errors or anything.
The output is now 6, 9, 9, 11.
However, even with pre-incrementation, shouldn't the first value result in 7?
If the macro is being called twice, then doesn't it go like this:
unsafe(x) // pre-incrementation doesn't modify the value when called.
unsafe(++x) // for all intents and purposes, the incrementation happens before the second call, so the ++x. This is for the first ans = unsafe(x++) if it's being called twice.
By the time we reach the second ans = unsafe(++x), shouldn't the x have been incremented twice? Once by the double call and once when the first double call was finished?
Instead of:
#define unsafe(i) \
( (i) >= 0 = (i) : -(i) )
I think you want:
#define unsafe(i) \
( (i) >= 0 ? (i) : -(i) )
In response to your edit:
After the first call to unsafe(x++), x is 7, even though the ans is 6. This is because you have the statement:
ans = ( (x++) >= 0 ? (x++) : -(x++) )
ans is assigned to the middle x++ after the left-most x++ is evaluated. As a result, ans == 6 but x == 7. The difference with unsafe(++x) is that ans is assigned to ++x, meaning the result is ans == x == 9.