#define prod(a) (a*a)
using namespace std;
int main()
{
int i = 3, j, k, l;
j = prod(i++);
cout << i << endl;
k = prod(++i);
cout << i << endl;
l = prod(i+1);
cout << i << " " << j << " " << k << " " << l;
}
Why is variable "i" incremented twice?
i.e to 5 from 3 after j=prod(i++);
Remember that macros are expanded in the source code, not actually called or evaluated.
That means a "call" like
prod(i++)
results in the expanded code
i++*i++
being seen by the compiler.
Many compilers allow you to stop after preprocessing, or otherwise generate preprocessed source, that you can examine to see macro expansions.
If you continue using such a macro with other expressions as arguments, you will soon see another reason they are bad.
Lets say you use
prod(2+4)
Then that will result in the expansion
2+4*2+4
which is equal to
2+(4*2)+4
which is equal to 14, not 36 which might have been expected.
Why is variable "i" incremented twice? i.e to 5 from 3 after j=prod(i++)
Because prod() is a macro, not a function, so
k=prod(++i);
become
k=(++i * ++i);
Related
I have a program which prints a statement based on inputs. The print statement prints using all inputs, but I only want it to print inputs which are actually given. For instance:
std::cout << "-Number: " << number < "-Letter: " << letter << "-String: " << str << "-Sum: " << sum << std::endl;
(for the purpose of demonstration, the variables above are arbitrary, this is just to show a point)
So this print statement is called after every iteration of a loop. The values can be anything, but I do not want it to print if a value was not received. Ideally, this would be done like so:
// Get input... Then print statement...
// If input was not received for a value (i.e. it equals none) then skip that value
std::cout << "-Number: " << number < "-Letter: " << letter << "-String: " << str << "-Sum: " << sum << std::endl;
number = none, letter = none, str = none, sum = none // reset inputs and repeat loop
(Once again, the above is pseudo-code for the purpose of demonstration)
Is this possible in C++?
If you have C++17 or a later version see optional. Prior to that, you would need to wrap your type into a proper struct that would mimic what optional does (of which you can find various implementation on the net, e.g. https://github.com/TartanLlama/optional).
In your example, you could do:
std::optional<int> number;
// Puts a value inside number
if (some condition)
number.value() = 44;
// Set number to invalid
else number.reset();
std::cout << "Number: " << (number ? number.value() : "Some Default Value You want to Show" << std::endl;
std::optional has an operator bool() which tells you if you correctly have a value in your std::optional. Also note that your std::optional is invalid by default if you call the default constructor (see https://en.cppreference.com/w/cpp/utility/optional/optional).
I'm just a beginner at C++ and I came across this instance.
#include <iostream>
using namespace std;
int main(){
int c = 3;
int d = c++;
if (c++ == 4 && d == 3)
cout << "1: " << c << " " << d << endl;
if (++c == 5 && d-- == 3)
cout << "2: " << c-- << " " << d << endl;
cout << "3: " << c << " " << d << endl;
}
So in this case, the output would be:
1: 5 3
3: 6 3
And what I understand from this is that the variables would still be updated even if they are being called for an increment in the if statement.
Now I came across this:
#include <iostream>
using namespace std:
int main(){
for (int i= 1; i <= 10; ++i){
cout << i ;
break
}
}
And even though its being incremented it's only returning 1. So I thought that maybe the 2nd time it goes through the loop (after removing the break of course) it would return 3, cause then it would have passed through ++i twice, but it's still 2. I don't understand. So my question is why would there be an instant increment in the if statement but there is none when ++i exists in the for loop ?
EDIT: just fixed a typo. I was supposed to type semicolon but put a comma instead :b
EDIT: added a more straightforward question as some are wondering what I am asking.
A for statement has 4 parts, they are not in the order they are executed.
for ( init-statement condition; iteration_expression) statement
Is defined as equivalent to
{
init_statement
while ( condition ) {
statement
iteration_expression ;
}
}
Except that
Names declared by the init-statement (if init-statement is a declaration) and names declared by condition (if condition is a declaration) are in the same scope (which is also the scope of statement).
continue in the statement will execute iteration_expression
Empty condition is equivalent to while(true)
I have a struct that contains an int but when I call the following...
typedef std::map<char, MessageLetter> Letters;
...
Letters lList;
...
MessageLetter m = lList[letter];
std::cout << "Before " << m.count << std::endl;
int c = ++m.count;
m.count = c;
std::cout << "After " << m.count << std::endl;
I am new to C++ and I am guessing this is a pointer issue but the output is...
Before 1
After 2
Before 1
After 2
I would expect...
Before 1
After 2
Before 2
After 3
I think you actually want:
MessageLetter & m = lList[letter];
I'm assuming this statement is part of a body of a loop:
MessageLetter m = lList[letter];
On each iteration of the loop, you're copying alList[letter] into m. Any modifications to m will be lost after the loop iteration completes. You will not modify lList[letter].
If you want to modify lList[letter], you either need to modify it directly, or make m a reference to it:
MessageLetter& m = lList[letter];
If you do not want to modify lList[letter], then you need to move the above assignment outside the loop to someplace above the loop.
The arrays are passed by reference. Any changes made to the array within the function changeArray will be observed in the calling scope (main function here).
However the codes below print 0 1 in the 1st cout, and print 2 in the 2nd "cout". What I don't understand is that why the first cout prints the original value of array[0]=1 instead of the changed value of array[0]=2?
Thanks a lot.
#include <iostream>
using namespace std;
int changeArray(int array[]) {
array[0]=2*array[0];
return 0;
}
int main() {
int array[]={1,2,3,4};
cout << changeArray(array) << " " << array[0] << endl;
cout << array[0] << endl;
return 0;
}
To make sure that the compiler doesn't reorder the execution:
cout << array[0] << endl;
changeArray(array);
cout << array[0] << endl;
This prints 1 and then 2.
The C++ compiler is allowed to optimize the code by reordering the execution of code within a single expression (e.g. cout << changeArray(array) << " " << array[0] << endl). To avoid that, and to make sure changeArray gets called first, you need to split your expression to separate statements, e.g. by using the semicolon (;). Everything before the semicolon gets executed before anything after the semicolon can start.
When I compile the following code snippet and run it, I expect it to print statement at line no. 12 too. But that doesn't happen? Why is that so? How does compiler handles a comment in if block?
1 #include <iostream>
2 using namespace std;
3
4 int main() {
5 int a;
6 if (false)
7 cout << "This will not be printed." << endl;
8 cout << "This will be printed anyway." << endl;
9
10 if (false)
11 // comment
12 cout << "This should also be printed. But not. Why?" << endl;
13 a = 100;
14
15 cout << "a = " << a << endl;
16 }
produces:
hyper150:~ 1041$ g++ what_if.cpp
hyper150:~ 1042$ ./a.out
This will be printed anyway.
a = 100
There is no trace of comments what so ever in the produced native language code.
Your code is equivalent to this:
1 #include <iostream>
2 using namespace std;
3
4 int main() {
5 int a;
6 if (false)
7 cout << "This will not be printed." << endl;
8 cout << "This will be printed anyway." << endl;
9
10 if (false)
11 cout << "This should also be printed. But not. Why?" << endl;
12 a = 100;
13
14 cout << "a = " << a << endl;
15 }
And since the condition at line 10 [new code] is never met - the cout at line 11 never occures
It's not printed because you have if(false) in front of it and if (false) never evaluates to true.
Compiler ignores comments.
And one more advice: In if statements like this one it's better when you write curly braces even if there is just a single statement.
if (false)
cout << "This should also be printed. But not. Why?" << endl;
is better to write like:
if (false)
{
cout << "This should also be printed. But not. Why?" << endl;
// Most likely you are going to add more statements here...
}
If you don't use brackets, the if will only take the next expression:
if (false)
cout << "This will not be printed." << endl;
cout << "This will be printed anyway." << endl;
if (false)
// comment
cout << "This should also be printed. But not. Why?" << endl;
a = 100;
is equivalent to:
if (false)
{
cout << "This will not be printed." << endl;
}
cout << "This will be printed anyway." << endl;
if (false)
{
// comment
cout << "This should also be printed. But not. Why?" << endl;
}
a = 100;
Comments are removed long before the actual compilation.
If you do not use braces to surround the conditional result, then the conditional result terminates with the end of the next statement, which usually means the ; character.
But it is not only the ; character, because you can do this (which is really horrible to read):
if (true)
for(int i = 0; i < 5; i++)
if (i == 4)
break;
else
h = i;
In this case the for loop is the next occurring statement, which is a iteration-statement that terminates after the h=i statement.
Everyone has their own tastes with the bracket conventions - I prefer to use bracketless if statements only if there is only one line under it which does not need a comment (if there are else statements, then I use brackets).
Code optimization is one of the phases of compilation. During this your commented code is removed from the code which actually produces the binary. So it interprets it as
if (false)
cout << "This should also be printed. But not. Why?" << endl;
And you have put a false within the if condition so ....you know the consequences.
Line endings are not significant in C++; the if controls the following
statement. In your second case, the following statement is the output,
so it should not be printed. Comments are not statements (an are in
fact replaced with white space before actual parsing). Thus:
if ( false ) std::cout << "no" << std::endl;
if ( false )
std::cout << "no" << std::endl;
if ( false )
std::cout << "no" << std::endl;
will output nothing.