I feel like an idiot. When I pass a variable to the function it results in a strange output like 6.2+e003 instead of the value that the variable holds. What am I doing wrong?
The x in main and the x in the function are different?
main:
int x, y;
while(system.WindowOpen())
{
x++;
y++;
bg.Draw2D();
bob.Think(x, y);
riley.Think(x, y);
system.Render(0);
}
class method:
void Organism::Think(double x, double y)
{
std::cout << "X: " << x << "\n";
std::vector<double> food;
food.push_back(x);
food.push_back(y);
std::cout << "VECTOR: " << food[0] << " " << food[1] << "\n";
std::vector<double> path;
if(refresh.IsTime()) {
std::cout << "\nFOOD VECTOR: \n" << food[0]
<< "\n" << food[1] << "\n";
path = brian.GetOutput(food);
organism.Translate2D(path[0], path[1]);
if(organism.IsOffScreen2D(resX, resY) == 'l' )
organism.SetPos2D(resX, organism.GetY());
if(organism.IsOffScreen2D(resX, resY) == 'r')
organism.SetPos2D(0, organism.GetY());
if(organism.IsOffScreen2D(resX, resY) == 't')
organism.SetPos2D(organism.GetX(), resY);
if(organism.IsOffScreen2D(resX, resY) == 'b')
organism.SetPos2D(organism.GetX(), 0);
};
font.DrawNumber2D(x, 50, 50);
font.DrawNumber2D(y, 50, 100);
organism.Draw2D();
}
Both x and y are uninitialized here:
int x, y;
so they can hold any value, and reading from them is undefined behaviour. You should initialize them:
int x = 0
int y = 0;
I was writing outside the bounds of a vector. I switched from using the [] operators to using the .at() and found my bug right away. Just a bit of memory corruption. I feel quite silly. Thanks all!
Related
I am learning C++ and I have code:
float x, y;
namespace X {
void SetMyX(float p) {
x = p;
}
void SetMyY(float p) {
y = p;
}
namespace XY {
void Set(float p = 0.0f) {
x = p;
p = y;
}
}
}
int main() {
X::SetMyX(5.4f);
std::cout << "x = " << x << " y = " << y << std::endl;
X::SetMyY(4.1f);
std::cout << "x = " << x << " y = " << y << std::endl;
X::XY::Set();
std::cout << "x = " << x << " y = " << y << std::endl;
return 0;
}
And output is:
x = 5.4 y = 0
x = 5.4 y = 4.1
x = 0 y = 4.1
And I figure out variable p sets value of x and then y sets value of p? But, how it is possible? In C++ you can also set value of function's argument or what?
It's just weird for me because I thought you can't just "editing" entered value and you must add another variable like result or something like that, or just return sum of two arguments, but change them?
Yes, the argument p is a completely normal variable and you can do everything with it.
This will also work in many other languages like C, Java, Javascript or Python.
I have the simplest question ever. I was practising with the if statement and wondered if I could print out different messages under different conditions, but I wanted to keep it simple. If the 1st condition is true, the 1st line of cout will print; and if the 2nd condition is true, the 2nd line of cout will print; and so on. Code follows;
int x; cin >> x;
int y; cin >> y;
if(x<y||x>y||x==y)
{
cout << x << " is smaller than " << y << endl;
cout << x << " is bigger than " << y << endl;
cout << x << " is equal to " << y << endl;
}
Apparently there is something missing, some kind of ||s between the couts. Is it possible to keep this code as compact as it is and make it function properly?
To do what you ask, your code should be:
int x; cin >> x;
int y; cin >> y;
if(x<y)
{
cout << x << " is smaller than " << y << endl;
}
else if (x>y)
{
cout << x << " is bigger than " << y << endl;
}
else
{
cout << x << " is equal to " << y << endl;
}
In other words, your three conditions have to be in separate parts of the if-else if-else control structure. This way, one of them executes based on your inputs and the corresponding message is printed out.
What to you mean by simple? If compact, then this is correct (but not the most readable) . .
x==y?cout<<"x=y":(x<y?cout<<"x<y":cout<<"x>y");
. . or go crazy and make == the default case to save a char
x>y?cout<<"x>y":(x<y?cout<<"x<y":cout<<"x=y");
it helps to think mathematically about these situations. if there are three possible cases (<, >, and =), then you need to test twice. in the code below, two tests are done to determine if the relationship is less than, or greater than; if either, then the proper output is issued. assuming that neither of the above is true, then the only other possibility is equal. that is handled by the else. chaining if...else if...else statements together is the general solution. the switch keyword exists for a more limited approach.
#include <iostream>
using namespace std;
int main() {
int x;
cout << "Enter x: ";
cin >> x;
cout << "Enter y: ";
int y; cin >> y;
if (x < y)
cout << x << " is smaller than " << y << endl;
else if (x > y)
cout << x << " is bigger than " << y << endl;
else
cout << x << " is equal to " << y << endl;
}
You can go like this:
int x; cin >> x;
int y; cin >> y;
if(x<y) {
cout << x << " is smaller than " << y << endl;
} else if (x>y) {
cout << x << " is bigger than " << y << endl;
} else if (x==y) {
cout << x << " is equal to " << y << endl;
}
Or if you feel adventurous just:
} else {
cout << x << " is equal to " << y << endl;
}
you use the magic of ternary operator:
#include <iostream>
int main()
{
int x, y;
std::cin >> x >> y;
(x == y) ? (std::cout << x << " is equal to " << y << std::endl) :
((x < y) ? (std::cout << x << " is smaller than " << y << std::endl) :
(std::cout << x << " is bigger than " << y << std::endl));
return 0;
}
If you want to go completely overboard you could abuse the template system a little.
auto if_ = make_if(
std::greater<>{}, [](auto x, auto y){ cout << x << " is greater than " << y << endl; },
std::less<>{}, [](auto x, auto y){ cout << x << " is smaller than " << y << endl; },
std::equal_to<>{}, [](auto x, auto y){ cout << x << " is equal to " << y << endl; }
);
if_(0,0);
if_(0,1);
if_(1,0);
Would yield
0 is equal to 0
0 is smaller than 1
1 is greater than 0
live demo
Here's full implementation of this:
template<typename Pred, typename Result, typename... Others>
struct If;
namespace detail
{
template<typename... Ts>
struct IfSelector
{
using type = If<Ts...>;
};
template<>
struct IfSelector<>
{
struct EmptyIf
{
template<typename... Ts>
void operator()(Ts&&...){}
};
using type = EmptyIf;
};
template<typename... Ts>
using ParentIf = typename IfSelector<Ts...>::type;
}
template<typename Pred, typename Result>
struct IfEntry
{
Pred pred;
Result result;
};
template<typename Pred, typename Result, typename... Others>
struct If : detail::ParentIf<Others...>
{
using pred = Pred;
using result = Result;
using parent = detail::ParentIf<Others...>;
template<typename P, typename R, typename... Os>
If(P&& p, R&& r, Os&&... os):
parent{std::forward<Os>(os)...},
entry{std::forward<P>(p), std::forward<R>(r)}
{}
template<typename... Ts>
void operator()(Ts&&... ts) {
if(entry.pred(ts...)) {
entry.result(std::forward<Ts>(ts)...);
} else {
this->parent::operator()(std::forward<Ts>(ts)...);
}
}
IfEntry<Pred, Result> entry;
};
template<typename... Ts>
auto make_if(Ts&&... ts){
return If<Ts...>(std::forward<Ts>(ts)...);
}
Basically, you pass a list of predicate-result pairs to the template, and they're checked in the reverse order. If a predicate yields true, the paired action is executed.
If you really want it short, and don't care much about readability, start with an array of labels:
static char const *names[] = {" is smaller than ", " is equal to ", " is bigger than "};
Then use ugly Boolean logic to index into that:
std::cout << x << names[1 + (y<x)-(x<y)] << y << '\n';
To figure out that logic, keep in mind that a<b produces either false (which will convert to 0) or true (which will convert to 1).
So:
if x < y => y<x = 0, x<y = 1, 0-1 = -1
if y == x => y<x = 0, x<y = 0, 0-0 = 0
if y < x => y<x = 1, x<y = 0, 1-0 = 1
Then add one to get the -1...1 to be 0..2 instead, and use that to index into the array.
Seriously though: if you're going to do something like this, at least wrap the comparisons up into a cmp(x,y) or something on that order:
int cmp(int x, int y) { return y<x - x<y; }
Then use that in the other code:
std::cout << names[1+cmp(x, y)] << '\n';
That doesn't eliminate the unreadable bit of code, but at least it restricts it to one little place (and lets you replace it with more normal logic when you're sick of its excessive cuteness, without having to edit the rest of the code).
For what it's worth (not much) this cmp function is defined to produce the same type of result as expected by qsort and bsearch.
I am reading through the C++ lambda section in chapter 3 of this book and the following code confuses me:
int x = 0;
int y = 42;
auto qqq = [x, &y] {
std::cout << "x: " << x << std::endl;
std::cout << "y: " << y << std::endl;
++y;
};
x = y = 77;
qqq();
qqq();
std::cout << "final y: " << y << std::endl;
This code prints out:
x: 0
y: 77
x: 0
y: 78
final y: 79
Why does qqq() not register that x has changed to 77? It was stated that passing by value means we can read but not modify data readable where the lambda was defined. Does that mean we can't see changes after it's definition?
That's because the variable is captured by value (i.e. copied) only once, when you define the lambda. It's not "updated" as you may believe. The code is roughly equivalent to:
#include <iostream>
int x = 0;
struct Lambda
{
int _internal_x; // this is used to "capture" x ONLY ONCE
Lambda(): _internal_x(x) {} // we "capture" it at construction, no updates after
void operator()() const
{
std::cout << _internal_x << std::endl;
}
} qqq;
int main()
{
qqq();
x = 77; // this has no effect on the internal state of the lambda
qqq();
}
Live on Coliru
By binding a variable by value to a lambda closure, you're effectively copying the value of the variable into a separate variable that is found inside the lambda object. Likewise, by binding a variable by reference, you're making such an internal variable to be a reference to the original variable instead, thus being able to "see changes" on the original variable.
Look at it like this. The following code...
#include <iostream>
int main()
{
int x = 0;
int y = 42;
auto qqq = [x, &y] {
std::cout << "x: " << x << std::endl;
std::cout << "y: " << y << std::endl;
++y;
};
x = y = 77;
qqq();
qqq();
std::cout << "final y: " << y << std::endl;
}
Is (kind of, but not exactly) syntactic sugar for...
#include <iostream>
class MyLambda
{
private:
int x;
int& y;
public:
MyLambda(int x, int& y) : x(x), y(y) {}
void operator()()
{
std::cout << "x: " << x << std::endl;
std::cout << "y: " << y << std::endl;
++y;
}
};
int main()
{
int x = 0;
int y = 42;
MyLambda qqq = MyLambda(x, y);
x = y = 77;
qqq();
qqq();
std::cout << "final y: " << y << std::endl;
}
With the exception of the special lambda syntax and the fact that you can't reference the lambda's type directly. By comparing the former with the later code, you should be able to clear out your understanding of closures.
The lambda uses the value at the time the lambda is defined (it makes a copy), not at the time it is invoked.
This might help: How are Lambda Closures Implemented?
EDIT:
So it seems like everyone is getting the correct output, so my question is now this: Why am I getting the wrong output? Why is the second argument, y, getting changed to zero, regardless if I use a variable or a literal? And no, I didn't get confused and put the wrong variable, I double checked. I am using Visual Studio 2013.
I'm doing an exercise from the fifth edition of the C++ primer by Lippman, Lajoie, and Moo on page 250, and my code for the third exercise, 6.56, is returning incorrect values.
I made a vector of pointers to function of type int (int, int), made four functions of that type (addition, subtraction, multiplication, and division), and added pointers to them to my vector. I attempted to move through those pointers with an iterator, dereferencing them to call them, but for add2 and subtract, it returned the value of the first argument, 0 for mult, and the else clause for divide, even though y was not equal to 0.
The code is as follows:
int test(int x, int y);
int add2(int x, int y);
int subtract(int x, int y);
int mult(int x, int y);
int divide(int x, int y);
typedef decltype(test) *FuncP; //type declaration of a ptr to a function that takes two ints and returns int
int main(){
//6.7
vector<FuncP> ptrsToFuncs;
ptrsToFuncs.push_back(*add2);
ptrsToFuncs.push_back(*subtract);
ptrsToFuncs.push_back(*mult);
ptrsToFuncs.push_back(*divide);
vector<FuncP>::iterator fIter;
int test1 = 6, test2 = 8;
int test3 = 0;
cout << "Running four arithmetic functions with " << test1 << " and " << test2 << "\n\n";
for (fIter = ptrsToFuncs.begin(); fIter != ptrsToFuncs.end(); ++fIter)
{
int result = (*fIter)(test1, test2);
cout << result << endl;
}
system("PAUSE");
}
int test(int x, int y)
{
if (y != 0)
{
cout << "Modulo of one and two is: " << x % y << "\n\n";
return x % y;
}
else
{
cout << "Cannot divide by zero.\n\n";
return -1;
}
}
int add2(int x, int y)
{
cout << "Adding " << x << " and " << y << ": ";
return (x + y);
}
int subtract(int x, int y)
{
cout << "Subtracting " << x << " and " << y << ": ";
return (x - y);
}
int mult(int x, int y)
{
cout << "Multiplying " << x << " and " << y << ": ";
return (x * y);
}
int divide(int x, int y)
{
if (y != 0)
{
cout << "Dividing " << x << " and " << y << ": ";
return (x / y);
}
else
{
cout << "Cannot divide by zero.\n";
return -1;
}
}
For example, with test1 = 6 and test2 = 8, the return values would be: 6, 6, 0, "Cannot divide by zero." -1.
I also tried this: (**fIter)(test1, test2). I thought that maybe I didn't dereference enough and needed to dereference the pointer to the function as well as the iterator, but it resulted in the same output.
Thank you.
Your code works fine for me, I think possibly you mixed up your variables inside your iteration (replaced test2 to with test3)
for (fIter = ptrsToFuncs.begin(); fIter != ptrsToFuncs.end(); ++fIter)
{
int result = (*fIter)(test1, test3);
cout << result << endl;
}
would give you
6, 6, 0, "Cannot divide by zero." -1.
If you need to see what your code is doing, try replacing your variables with literals and also adding some couts to your function calls.
for (fIter = ptrsToFuncs.begin(); fIter != ptrsToFuncs.end(); ++fIter)
{
int result = (*fIter)(12, 24);
cout << result << endl;
}
int add2(int x, int y)
{
cout<<"add function called with first variable"<<x<<" and second variable"<<y<<endl;
return (x + y);
}
I was wondering if anyone could help me with a more elegant way to code this program that I am writing please. The code I have is bellow, I would like to know if there is a way to separate the part that prints out the totals into a new function. I have tried but I always just get the total is 0, so I must be passing things wrong or something.
void printNumbers(int x, double y, double z, double v, int sum, double sum2,int sum3,int sum4){
while(x != 0){
y = sqrt (x);
z = pow (x,2);
v = pow (x,3);
sum = sum + x;
sum2 = sum2 + y;
sum3 = sum3 + z;
sum4 = sum4 + v;
cout << " " << x << setw(12) << setprecision (4) << y << setw(8) << z << setw(8) << v << endl;
x--;
}
cout << " total is" << sum << setw(12) << sum2 << setw(8)<< sum3 << setw(8) << sum4 << endl;
}
This is what I tried, at the time I only had one total to get, but It still did not work just gave the answer 0:
void printFooters(int sum){
cout << " " << "====================================="<< endl;
cout << "Totals " << sum << endl << endl;
cout << " " << "====================================="<< endl;
}
This is how I was calling it in main():
printFooters(sum);
You need to make the sums into references if you want them to be updated.
void printNumbers(int x, double y, double z, double v, int& sum, double& sum2,int& sum3,int& sum4)
If you don't the sums are passed by value, so you just get a copy of the current value of the sums.
Alternatively you can use pointers to the sums, but that would involve changing the syntax when accessing the sum variables.
You should decide first, what variables are input and what variables should carry output. Try to not use one variable for both input and output, it is often more confusing than valuable.
Only input value is x. Everything else is output values. In way you have used that values, content of values is modified only in local copy inside function printNumbers(). They will get lost on end of function. I expect you want to output computed results from function (however then printNumbers is wrong name for that function).
C and C++ always pass variables to function parameters by value. That means, variable is initialized from parameter, but any changes are done only inside function. At the end of function, copy is discarded and will NOT change anything you passed to it.
If you want output from function, you can use return, or use pointers or references to a variable. I suggest to use references in C++, they are easier to understand and easier to use.
Use references instead of copied variables in function. Then, when you modify that value inside function, it will keep modified value after function return.
void f1(int in, int out)
{
out = in + 1;
}
void f2(int in, int &out)
{
out = in + 1;
}
int o1=-1, o2=-1;
f1(1, o1);
f2(1, o2);
cout << o1 << "," << o2 << endl; // will print -1,2
So declare your function as:
void printNumbers(int x, double &y, double &z, double &v, int &sum, double &sum2,int &sum3,int &sum4);
you can then do:
double y,z;
int sum, sum2, sum3, sum4;
printNumbers(4, y, z, sum, sum2, sum3, sum4);
printFooters(sum);
And this time, it should print whatever printNumbers computed. See http://www.cprogramming.com/tutorial/references.html for a bit more, or use google.
You could batch all those parameters into structs, and separate all the calculations and outputs.
This is probably overkill in your case, and is quite a bit of code, but anyway...
struct Powers
{
double sqroot;
int one;
double square;
double cube;
};
Powers calculatePowers(int x)
{
Powers powers;
powers.sqroot = sqrt(x);
powers.one = x;
powers.square = x * x;
powers.cube = x * x * x;
return powers;
}
struct Sums
{
int sum1;
double sum2;
int sum3;
int sum4;
};
Sums addPowers(Sums sums, Powers powers)
{
sums.sum1 += powers.one;
sums.sum2 += powers.sqroot;
sums.sum3 += powers.square;
sums.sum4 += powers.cube;
return sums;
}
void printPowers(Powers powers)
{
cout << " " << powers.one
<< setw(12) << setprecision (4) << powers.sqroot
<< setw(8) << powers.square
<< setw(8) << powers.cube
<< endl;
}
void printTotals(Sums sums)
{
cout << " total is"
<< sums.sum1
<< setw(12) << sums.sum2
<< setw(8) << sums.sum3
<< setw(8) << sums.sum4
<< endl;
}
void doEverything(int x)
{
Sums sums = {0, 0, 0, 0};
while (x > 0)
{
Powers powers = calculatePowers(x);
printPowers(powers);
sums = addPowers(sums, powers);
x--;
}
printTotals(sums);
}