C++ Not getting expected result when executing a Macro - c++

#include <stdio.h>
#define swapOut(a,b) a+b-a, a+b-b
int main()
{
int a = 5;
int b = 6;
printf("%d,%d", swapOut(a+b,b-a));
return 0;
}
When executing this program, I am expecting the output to be "1,11", but the actual output is "13,1". Can someone explain what is happening here ?

To understand what's happening, you have to realise that macros are not like functions; they perform very simple text substitution. Thus, when you define
#define swapOut(a,b) a+b-a, a+b-b
and then use it as swapOut(a+b,b-a), it is expanded as a+b+b-a-a+b, a+b+b-a-b-a. With the values a=5 and b=6 this results in 13,1.
So here's a valuable lesson: always surround the arguments in macros with parentheses. The corrected version of your program is
#include <stdio.h>
#define swapOut(a,b) ((a)+(b)-(a)), ((a)+(b)-(b))
int main()
{
int a = 5;
int b = 6;
printf("%d,%d", swapOut(a+b,b-a));
return 0;
}
This indeed outputs 1,11 as you expected.

To achieve this, you have to localize the value first.
#include <stdio.h>
#define swapOut(a,b) a+b-a, a+b-b
int main()
{
int a = 5;
int b = 6;
int c = a + b;
int d = b - a;
printf("%d,%d", swapOut(c,d));
return 0;
}

Related

How do I add numbers in C++ again?

Seriously, I don’t remember..
Would an integer work??
But I don’t know why its not working...
I'm trying to add integers, like this.
int main() {
i = 1;
b = 3;
}
Signed int addition() {
i + b
}
You can't use functions and variables, including local variables, parameters, etc before they have been declared first. Though, you can initialize variables at the same time you declare them. For example:
#include <iostream>
int addition(int a, int b);
int main() {
int i = 1;
int b = 3;
int sum = addition(i, b);
std::cout << sum;
}
int addition(int a, int b) {
return a + b;
}
You have a lot of syntax errors in that code. Until you are more comfortable with programming, just start with a simple working "Hello world" example, and add one line of code at a time, compiling after each line you add. Look carefully at the error messages the compiler gives you and fix them before adding another line. You might arrive at something like this:
int main() {
int i = 1;
int b = 3;
return i + b;
}
When you run this and check the process return code (e.g. using$? in Bash) then you would get 4.
It should not be hard.
// [...]
int Add(int x, int y) { return x + y; }
using namespace std;
int main(void) {
int a = 1, b = 2;
printf("%d\n", Add(a + b));
return 0;
}

Implementing square() without using the multiplication operator

Task:
Implement square() without using the multiplication operator; that is, do the
x*x by repeated addition (start a variable result at 0 and add x to it x times).
Then run some version of "the first program" using that square().
Solution #1:
#include <iostream>
int square(int x){
int result = 0; // same output of we declare result without initializing
for (int i = 0; i < x; i++) {
result += x;
}
}
int main() {
std::cout << square(19);
}
Output: 19.
Solution #2:
#include <iostream>
int square(int x){
int result = 0;
for (int i = 0; i < x; i++) {
return result += x;
}
}
int main() {
std::cout << square(19);
}
Output: 19.
Solution #3:
#include <iostream>
int square(int x){
int result;
for (int i = 0; i < x; i++) {
return result += x;
}
}
int main() {
std::cout << square(19);
}
Output: 22006.
Why does only the third one work?
Solution #1
You don't return result, thus you calculate it but never return it
i.e.
#include <iostream>
int square(int x){
int result = 0; // same output of we declare result without initializing
for (int i = 0; i < x; i++) {
result += x;
}
return result;
}
int main() {
std::cout << square(19);
}
Solution #2
You return the result after the first iteration, this will always return x's value.
#include <iostream>
int square(int x){
int result = 0;
for (int i = 0; i < x; i++) {
result += x; // remove "return" here
}
return result;
}
int main() {
std::cout << square(19);
}
Solution #3
This is an interesting one. With languages like C++, you need to initialize your variables such as integers, see this for more info. Since you don't initialize it, your the integer gets a memory allocation and what ever is in memory at that point is what your int value is now. Since you only add to it, it will add the calculation to that value.
Thus, you need:
#include <iostream>
int square(int x){
int result = 0; // initialize values
for (int i = 0; i < x; i++) {
result += x; // remove return here
}
return result; // return result here
}
int main() {
std::cout << square(19);
}
This is invalid code: the function square is declared as int, but doesn't return anything.
You return prematurely, during the first iteration of the loop.
Same as #2, but with unitialized variable result - garbage.
You seem to have understood the task you have to accomplish. And you're very close to the result. But there's several major issues, which is why none of the provided solutions work.
Solution 1
You seem to be doing the task correctly, but never return the result. The fact that the output returns 19 in your case is surprising, but it won't always be like that. See here
Solution 2
You might to read up again on return. It returns the value immediately. So in essence, you're only doing one pass inside the loop, so you're only returning the parameter of the function, which in this case is 19.
Solution 3
This one has the same issue with return than the previous one. But you're also adding to an uninitialised value of result, and because of that can have litterally any possible value inside of it. Which is why you're getting a weird number as a result.
For Solution 1, never returning a value inside a function that expects a return value, and in Solution 3, accessing the value of an uninitialised value, are called undefined behaviours. In short, never have undefined behaviour in your code, it might work some times on some machines/compilers, but most of the time it will simply not work, or worse, "work" but in unpredictable ways, causing major issues and bugs.

Swap values of x and y

How can I change the values of x and y in this code?
When I try to do it by x=y, y=x; it changes it to the same numbers.
How can I do this?
How can I do this for 3 values like (x y z)?
#include <iostream>
using namespace std;
int main()
{
int x=4;
int y=6;
cout<<x<<y;
return 0;
}
I tried this code before but it isn't working the way I want it.
#include <iostream>
using namespace std;
int main()
{
int x=4;
int y=6;
x=y,y=x;
cout<<x<<y;
return 0;
}
This is because you first set x's value and then copy that value into y. There is a standard library function called std::swap, which should do the job.
You can see an exapmle of it here.
std::swap is defined in the header <algorithm> before C++11 and in <utility> since C++11. So make sure you #include the correct header.
The benefit of using std::swap in C++11 as opposed to having a third temporary variable that you copy the value into, is that std::swap uses std::move and thereby creates no additional copies.
For three numbers you'll have to make your own implementation like this:
#include <iostream>
int main() {
int x{5}, y{3}, z{2};
int temp{std::move(x)};
x = std::move(y);
y = std::move(z);
z = std::move(temp);
std::cout << x << ' ' << y << ' ' << z << '\n';
return 0;
}
Ideone
For 2 variables, you should use std::swap, for more variables, you may use std::tuple:
std::tie(x, y, z) = std::make_tuple(y, z, x);
Demo
There are two options:
Introduce temporary variable:
int temporary = y;
y = x;
x = temporary;
Or use std::swap like this std::swap(x, y); (you might need to import <algorithm> or <utility>)
Now why you are getting this error? Let's analyze what you are doing here step by step:
x = y; Give x value of y. So now x is equal to y
y = x; Give y value of x. But wait, x is now equal to y. So nothing changes.
If you still have trouble understanding what you did wrong I suggest taking a piece of paper and following your own code step by step on paper writing state of program at each step.
And one last thing as advice for the future. Please make you questions clear and properly formatted. For example, it totally don't understand your point with 3 values. Please explain what you mean and probably provide some example and then maybe someone will be able to help you.
try this:
#include <iostream>
using namespace std;
int main()
{
int x=4;
int y=6;
int temp=x;
x=y;
y=temp;
cout<<x<<y;
return 0;
}
Without using a third variable you can do swapping two variables like this,
#include <iostream>
using namespace std;
int main()
{
int x=4;
int y=6;
x = x + y;
y = x - y;
x = x - y;
cout<<"X = "<<x << "\n"
<<"Y = "<<y;
return 0;
}
So the output will be,
X = 6
Y = 4
x=4
y=6
x=y // x=6, y=6
y=x // does nothing
Try using another variable:
#include <iostream>
using namespace std;
int main()
{
int x=4;
int y=6;
int temp=x;
x=y,y=temp;
cout<<x<<y;
return 0;
}
Here is code to swap 2 variables(1 line)
#include <iostream>
using namespace std;
int main()
{
int x = 4;
int y = 6;
cout << x<< y;
swap(x,y);
cout << x << y;
getchar();
return 0;
}
Here is code to swap 3 variables(1 line)
#include <iostream>
#include <tuple>
using namespace std;
int main()
{
int x = 4;
int y = 6;
int z = 8;
cout << x<< y<<z;
tie(x, y, z) = make_tuple(y, z, x);
cout << x << y << z;
getchar();
return 0;
}

Visual studio C programming function defenition

The program below is to sort number in ascending order using a function. It is written in Visual Studio.
I know that I have made a mistake in function declaration as I have declared int LinearSort(); above main and not inside main.
The program executes without error but sorting does not happen since the function is not called.
The program is saved as C++.
Can anyone help me to call the function and do sorting by editing program below?
Main file
#include <stdio.h>
#include <stdafx.h>
#include "sort.h"
#include <conio.h>
#include <iostream>
int LinearSort();
int main()
{
int sort[50];
int i=0;
int j=0;
int k=0;
int a = 0;
printf("Enter 10 Numbers");
for ( i = 0; i < 10; i++ )
{
scanf_s("%d",&sort[i]);
}
for ( i = 0; i < 10; i++ )
{
printf("%d\n",sort[i]);
}
return 0;
}
.C file
#include "stdafx.h"
#include "sort.h"
#include <stdio.h>
#include <conio.h>
#include <iostream>
void LinearSort(int i, int j, int k, int a, int sort[])
{
for ( j=0; j < i-1; j++ )
{
for ( k=0; k < i-j-1; k++ )
{
if(sort[k] < sort[k+1])
{
a = sort[k];
sort[k] = sort[k+1];
sort[k+1] = a;
}
else
{
sort[j] = sort[j];
}
}
}
for ( j = 0; j < i; j++ )
{
printf("ascending %d\n",sort[j]);
}
_getch();
}
Header file
#pragma once
#include <stdio.h>
extern void LinearSort(int i, int j, int k, int a, int sort[]);
You are on the right way and your code needs only a little tweeking. Others have given valuable suggestions, most of which I won't repeat.
First the definition of your LinearSort(). You are passing a number of variables (i..k) that we call local variables and that should not be passed. Local variables are only used by your function and are declared inside the function. The proper definition now becomes:
void LinearSort(int a, int sort[]); // prototype; put in header file or above main
void LinearSort(int a, int sort[]) // function itself
{
int i, j, k; // local variables
Then you must call it from your main, after you read all the data. Call it like:
LinearSort(10, sort[]);
You passs 10 for a because you read a fixed number of integers; would you have read an arbitrary number (but less than 50), you would have passed a variable with this amount.
For your information: you pass the array variable sort[] but note that this name sort is the same in your main and in your function. There is no need and this just coincidence.
As for the sort algorithm, it seems based on bubble sort but uses for-loops. That is at least unusual and probaby wrong; the outer loop must go as many times as is needed until no more elements have been exchanged; however, a for loop normally executes a fixed number of times, so you see why this is probably wrong. I suggest you read about bubble sort.
First, remove this statement
int LinearSort();
As you have already declared the function in header file and header is included in all files.
you should call LinearSort() with proper argument in your main() , after scanf() . And in your LinearSort() function, like this
int main()
{
int sort[50];
int i=0;
int j=0;
int k=0;
int a = 0;
printf("Enter 10 Numbers");
for ( i = 0; i < 10; i++ )
{
scanf_s("%d",&sort[i]);
}
LinearSort(i, j, k, a, sort);
for ( i = 0; i < 10; i++ )
{
printf("%d\n",sort[i]);
}
return 0;
}
And in LinearSort(), inside for loop,i don't see any specific use of else statement.

C++ macro (min max) not working properly

Why doesn't the following code work? It prints INT_MAX. But if I uncomment the two lines in the inner for loop, then it works fine (prints 2). I can't combine the two macros like that? Not sure if further detail is needed...pretty self explanatory.
Thanks.
#include <iostream>
#include <limits.h>
using namespace std;
#define min(a,b) a<b?a:b
#define max(a,b) a>b?a:b
int main(int argc, char **argv)
{
int N = 100;
int *drop = new int[N+1];
drop[0] = 0; drop[1] = 1; drop[2] = 1;
for(int i=3; i<=N; i++)
{
drop[i] = INT_MAX;
for(int start=1; start<=i; start++)
{
drop[i] = min(drop[i], max(start, drop[i-start]+1));
//int x = max(start, drop[i-start]+1);
//drop[i] = min(drop[i], x);
}
}
cout<<drop[3]<<endl;
return 0;
}
Put brackets around the terms in your macros:
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
As it is, this:
drop[i] = min(drop[i], max(start, drop[i-start]+1));
is expanding to this (without brackets):
drop[i] < start > drop[i-start]+1 ? start: drop[i-start]+1 ? drop[i] : start > drop[i-start]+1 ? start: drop[i-start]+1;
which may not evaluate in the order you intend. Using brackets enforces the correct order of operations.
As noted in the comments, you shouldn't use macros with expressions that have side effects if the macro arguments are evaluated more than once.
C++ already has std::min and std::max defined in <algorithm>. You can change your code to a pure C++ version
#include <iostream>
#include <algorithm>
#include <limits>
using namespace std;
int main(int argc, char ** argv) {
int N = 100;
int * drop = new int[N + 1];
drop[0] = 0;
drop[1] = drop[2] = 1;
for (int i = 3; i <= N; ++i) {
drop[i] = numeric_limits<int>::max(); // <limits>
for(int start = 1; start <= i; ++start)
drop[i] = min(drop[i], max(start, drop[i - start] + 1)); // <algorithm>
}
cout << drop[3] << endl;
return 0;
}
Rather than an answer, it's a plead to all developers out there: please don't use macros like that. C++ offers template functions for these purposes. Remember that macros just substitute parameters rather than pre-evaluating them. Even if you add parentheses as samgak explained, this only fixes a half of the problem. Consider code like this:
int x = 5;
int y = max(++x, 0);
The caller would expect x=6 and y=6 after that; however the macro will get expended into
int y = (++x > 0)? ++x : 0;
causing x=7 and y=7.