I started to read a book about C++ and found the following code.
It is an example on how you can send pass parameters by reference.
#include <iostream>
void swap(int &x, int &y);
int main()
{
int x = 5, y = 10;
std::cout << "Main. Before swap, x: " << x
<< " y: " << y << "\n";
swap(x, y);
std::cout << "Main. After swap, x: " << x
<< " y: " << y << "\n";
return 0;
}
void swap(int &rx, int &ry)
{
int temp;
std::cout << "Swap. Before swap, rx: " << rx
<< " ry: " << ry << "\n";
temp = rx;
rx = ry;
ry = temp;
std::cout << "Swap. After swap, rx: " << rx
<< " ry: " << ry << "\n";
}
.
Main. Before swap, x:5 y: 10
Swap. Before swap, rx:5 ry:10
Swap. After swap, rx:10 ry:5
Main. After swap, x:10, y:5
The logic is clear to me.
Now this may be a very stupid question (I'm not very experienced yet), but why can't you just declare private: int x as an instance variable? Isn't x in this case directly accessible everywhere in your class? (without the need for specifying parameters at all)? Thanks in advance for your answers!
For several reasons.
You should declare variables at the narrowest scope possible. Why? Look at 2 & 3
Variables are expensive, they take up memory, you only want them
around as long as you need them.
The greater a variables scope (i.e. how much code the variable is visible
to) the greater the chance that you will mistakenly use the
variable, and therefore it's value may change unexpectedly. This will be a bug, good luck hunting that one down.
Tight coupling (this is bad). If you write a class and put a swap method on the
class, and you write it so it uses instance member x (not method
variable x), then that swap method CAN ONLY EVER swap using x, if
in time you need it to swap on a different variable (or the
parameter of another method on the class) then you've to move the
value into x which is Inefficient & goto 5. Isn't it better to call the swap function with the values you have to hand, without needing to know there's a special x variable that you have to set first?
Error prone. Will this second method be called while another method
is using the swap method? What should the value of x be after it's
called? You're introducing lots of context around swap and knowing when it's
ok to call swap, and what can call swap. This is bad, the more self contained any piece of code is, then the less of have to worry about it, and about how it's used.
No other class can re-use your swap method, every class that needs a
swap method must implement it's own, and this is a huge big
no-no for more reasons than I can count here, but can sum up as it
voliates the DRY Principal
All of these problems can be removed by simply passing the values by reference. Bit of a no-brainer really :)
Hope this helps.
Passing values via arguments to a function ensures modularity in your code. It sounds like you're just starting out with C++, so I'm not sure how familiar you are with object oriented programming. Functions/methods represent a layer of encapsulation. Your swap() function should encapsulate the logic needed to perform its function/purpose. The caller should not be concerned with how this is accomplished. If your swap() function must assert there is a global variable available in the program, then it's not fully encapsulating the logic of "swapping".
Also, Lets say you wanted to reuse this function elsewhere in your class. It would be difficult and clumsy to use a set of global variables for calling this function. In addition, you may have other locations in your class that are referencing those global variables, and therefore your other calls to swap() would change those values, potentially causing confusion in other areas of the code.
Related
I have two integer variables i and j and I want to make a function which takes these two variables as its argument and interchanges their contents using xor operator. Now if I make the function to take arguments by value i.e void swap (int x , int y);(with function body same as for the function swap below) then the values are being swapped nicely within the function. But as what I want is the swapping of the values of the variables in the calling function I used passing arguments by reference (and by pointers as well) :
void swap ( int& x , int& y )
{
x^=y^=x^=y;
cout << x<< " " << y << endl ;
}
int main ()
{
int i (1), j (2) ;
swap ( i, j ) ;
cout << i << " " << j << endl ;
}
but neither case showed the correct result !
Why is the swap function not swapping the values on passing arguments by reference or pointers ?
I have two integer variables i and j and I want to make a function
which takes these two variables as its argument and interchanges their
contents using xor operator.
Why?
As you've figured out, you need either to pass pointers to the objects, or to use references.
This:
x^=y^=x^=y;
has undefined behavior, since it modifies the same object twice between sequence points (it does this for both x and y).
The xor trick fails if both objects are the same object; the first xor zeros the object.
If you want to swap two objects, just use a temporary:
int temp = x;
x = y;
y = temp;
It's simple, and it works.
As others have noted, this is a pretty silly optimization (if you can call it that). The problem is the chained use of in-place operators. Broken it into separable statements, it works.
x^=y; // values are X^Y, Y
y^=x; // values are X^Y, X
x^=y; // values are Y, X
Like the others, I would encourage you not to riddle your code with such clarity-killing cleverness unless you have a demonstrable need established by profiling and a demonstrable speedup for doing your bit twiddling hack. (cool site)
I have vector of integers filled with 5 numbers and i'm curious what exactly does [&idx] do in :
int idx = 0;
for_each ( x . begin (), x . end (), [&idx] ( const int & a ) { cout << idx ++ << " " << a << endl; } );`
Why it does not work like this ? :
int idx = 0;
for_each ( x . begin (), x . end (), ( const int & a, int & idx ) { cout << idx ++ << " " << a << endl; } );
Is it better from perfomance point of view than? :
for ( vector<int>::size_type i = 0; i < x . size (); i ++ )
cout << x[i] << endl;
I'm curious what exactly does [&idx] do
That's the lambda capture. It sets the lambda to take a reference to idx. It won't work as a parameter because for_each only passes one parameter to the predicate. If you made idx a parameter instead, it wouldn't compile.
Also is it better from a performance point of view?
Possibly. If you really want to know, test each way of doing it.
what exactly does [&idx] do in
the
[](){}
structure, as of C++11, is a lambda function - that is, an anonymous function which, in this context, will be callbacked with the vector elements passed as arguments. The [&idx] denotes that the variable idx which DOES NOT NORMALLY BELONG to the lambda's environment and which is NORMALLY INACCESSIBLE by the latter, should be instead accessible (captured) in it by reference. This means that you can use idx within the body of the lambda and that whenever you do so you are using a reference to the original variable. Therefore, the idx++ part of the code increments the original idx variable and not some local copy.
Why it does not work like this ?
because () {} structures are not a valid C++ expressions or statements.
Is it better from perfomance point of view than? :
Probably, but not necessarily, you should measure to find out for sure. However, it is both advisable and idiomatic to use iterators and algorithms rather than C-style loops. Given the standard "avoid premature optimisation" guideline, I suggest that you use the first version by default and when you're done with all development you can decide if you want to dedicate some time to try-out and measure alternatives such as the second. If this is not in some critical part of your program (such as in some callback function), I don't think it deserve the fuss, the difference would be very small anyway.
Just for reference, in my system, using clang++ with -O3 flag, 1000 iterations of your std::foreach version would last 4967ms while 1000 of the for one 3861ms. That's approximately 1second for 1000 iterations, e.g. 1ms if you only run this code once..
I have a logic that looks like the below (Not the actual code):
StructureElement x;
For i in 1 to 1000
do
x.Elem1 = 20;
x.Elem2 = 30;
push(x into a std::vector)
end
My knowledge is that x be allocated memory only once and that the existing values will be overwritten for every iteration.
Also, the 'x' pushed into the vector will not be affected by subsequent iterations of pushing a modified 'x'.
Am I right in my observations?
Is the above optimal? I would want to keep memory consumption minimal and would not prefer using new. Am I missing anything by not using new?
Also, I pass this vector and recieve a reference to it it another method.
And, if I were to read the vector elements back, is this right?
Structure element xx = mYvector.begin()
print xx.Elem1
print xx.Elem2
Any optimizations or different ideas would be welcome.
Am I right in my observations?
Yes, if the vector is std::vector<StructureElement>, in which case it keeps its own copies if what is pushed in.
Is the above optimal?
It is sub-optimal because it results in many re-allocations of the vector's underlying data buffer, plus unnecessary assignments and copies. The compiler may optimize some of the assignments and copies away, but there is no reason, for example, to re-set the elements of x in the loop.
You can simplify it like this:
std:vector<StructureElement> v(1000, StructureElement{20, 30});
This creates a size-1000 vector containing copies of StructureElement with the desired values, which is what you seem to be trying in your pseudo-code.
To read the elements back, you have options. A range based for-loop if you want to iterate over all elements:
for (const auto& e: v):
std::cout << e.Elem1 << " " << e.Elem2 << std::endl;
Using iterators,
for (auto it = begin(v); it != end(v); ++it)
std::cout << it->Elem1 << it->Elem2 << std::endl;
Or, pass ranges in to algorithms
std::transform(begin(v), end(v), ....);
I have a few questions related to portions of my code.
The first has to do with how I find the length of an array of arrays of strings. I'm using the following as a map for a Calculus tool I'm using.
std::string dMap[][10] = {{"x", "1"}, {"log(x)", "1/x"}, {"e^x", "e^x"}};
I'm wondering how to do the equivalent of
int arr[] = {1, 69, 2};
int arrlen = sizeof(arr)/sizeof(int);
with an array of elements of type std::string. Also, is there a better way of storing symbolic representations of (f(x), f'(x)) pairs? I'm trying to not use C++11.
My next question has to do with a procedure I wrote that isn't working. Here it is:
std::string CalculusWizard::composeFunction(const std::string & fx, const char & x, const std::string & gx)
{
/* Return fx compose gx, i.e. return a string that is gx with every instance of the character x replaced
by the equation gx.
E.g. fx="x^2", x="x", gx="sin(x)" ---> composeFunction(fx, x, gx) = "(sin(x))^2"
*/
std::string hx(""); // equation to return
std::string lastString("");
for (std::string::const_iterator it(fx.begin()), offend(fx.end()); it != offend; ++it)
{
if (*it == x)
{
hx += "(" + gx + ")";
lastString.erase(lastString.begin(), lastString.end());
}
else
{
lastString.push_back(*it);
}
}
return hx;
}
First of all, where's the bug in the procedure? It's not working when I test it out.
Second of all, when trying to make a string empty again, is it faster to do
lastString.erase(lastString.begin(), lastString.end());
or
lastString = "";
???
Thank you for your time.
Question 1) Understand that you can't, and really don't need to, calculate the size of a String this way. Just ask it how big it is and it will tell you.
// comparing size, length, capacity and max_size
#include <iostream>
#include <string>
int main ()
{
std::string str ("Test string");
std::cout << "size: " << str.size() << "\n";
std::cout << "length: " << str.length() << "\n";
std::cout << "capacity: " << str.capacity() << "\n";
std::cout << "max_size: " << str.max_size() << "\n";
return 0;
}
http://www.cplusplus.com/reference/string/string/capacity/
As for an array of strings, well go read this:
How to determine the size of an array of strings in C++?
Check out David RodrÃguez's answer.
Question 2) The better way might be to define a FunctionPair class depending on what you're doing with them. Vector<FunctionPair> might come in handy.
If FunctionPair doesn't end up with any behavior (functions) associated with it then a struct might be enough: std::pair<std::string, std::string> could also be shoved into a vector.
You don't need a map unless your going to use one function string to look up the other.
http://www.cplusplus.com/reference/map/map/
Question 3) A little better description of what's not working would help. I notice lastString doesn't impact hx at all.
Question 4) "Second of all" Fastest is nothing to worry about at this point. Write what is easiest to look at until all the bugs are gone. "Premature optimization is the root of all evil", Donald Knuth.
Tip: Look into how the replace function might help you do the composition replacements:
http://www.cplusplus.com/reference/string/string/replace/
As the above commenter said, you shouldn't use c-style arrays even if you just want to make things 'easy'.
In reality doing things like that makes things harder.
c-style arrays aren't bounds checked. That means they are a source of bugs due to memory unsafety and can lead to all kinds of issues from segfaulting to corrupting data as you read random data from unrelated blocks of memory or even worse write to them.
#include <iostream>
int main() {
int nums[] = {1, 2, 3};
std::cout << nums[3] << std::endl;
}
.
# ./a.out
4196544
No programmer is perfect, every time you implement something like that there is a percentage chance you will be off by one in your bounds or something. Even if you are some programming god most people have to work on a team with people who aren't. In many cases no one will even notice since not every time will cause anything obvious. Memory can be randomly corrupted without causing anything to crash horribly. Until you make a totally unrelated change that causes the memory to be in a different order.
But when you do notice it will often effect something totally unrelated that you code sometime later. Given the fact that you will likely implement many such arrays in your programming lifetime you will likely make things much worse for yourself, you save yourself 10 minutes for each project but end up spending hours tracking down a bug in one.
If you really don't want C++11 then use std::vector<std::vector<std::string>>. It will use a little more memory so you might loose some performance , but most of the time when people are worried about performance they shouldn't be. Are you are calling this function 10,000 time a second? Even then you could gain more performance from threading the code or preallocating memory. Most of the time people think something has bad performance but in reality the computer is optimizing it away, or the CPU is. Is the performance from the memory allocation going to be worse than trying to find the array size every run?
This is also the case with raw pointers vs std::unique_ptr, std::shared_ptr.
If typing all those names looks like a pain, use a typedef to make it nice.
You can also look at using Boost's Array type, boost::array. Or whip up your own custom class.
That's not to say that you should never use that stuff. But you should only use it when you can justify it. The default should be the 'pure' C++ style code.
Performance (only when you have measured and see that you need it there).
C compatibility (but most of the time you can just wrap that stuff in the std classes anyway).
If you do feel you need it then. Make sure you unittest your code. And look at using the address and memory sanitizers that ship in current versions of gcc and clang. And quarantine the code as much as possible (ie in classe)s.
That all sounds like a lot of work, but once you have learned to do it, it becomes a habit and build it into your build system then it's just part of the development process. As easy as make test. And once you have it in one build system, you cut and paste it into everything else you do forever. You have expanded your programmers toolkit. That's all good habits to form even if you don't do that.
But here's the actual answer to your array size question:
std::string arr[][10] = {
{"xxx", "111"},
{"y", "222"},
{"hello", "goodbye"},
{"I like candy", "mmmm"},
{"Math goes here", "this is math"},
{"More random stuff", "adsfdsfasf"},
};
int size = sizeof(arr) / 10 / sizeof(std::string);
std::cout << size << endl; // Prints 6, as in 6 pairs of strings
Since the semantics is similar as Map ( you are mapping a function to it's differential), I guess most suitable data structure would be std::map, when you can easily get the differential using the function as index.
About the function, you are not appending lastString.
return hx+lastString;
Question 1 is actually quite straightforward:
std::string dMap[][10] = {{"x", "1"}, {"log(x)", "1/x"}, {"e^x", "e^x"}};
size_t tupleCount = sizeof(dMap)/sizeof(dMap[0]);
size_t maxTupleSize = sizeof(dMap[0])/sizeof(dMap[0][0]);
assert(tupleCount == 3);
assert(maxTupleSize == 10);
Note that you won't get the actual count of strings in a tuple this way. You only get the amount of std::strings that can fit into each tuple. Of course, you can search your tuples for the first default constructed std::string it contains. But the entire setup is an invitation for bugs, so you don't want to use it anyways (see below).
Question 2 can also be answered quite clearly. You should be using an std::unordered_map<>. Why?
You usecase is to map strings of one class to another. That is the semantics of either std::map<> or std::unordered_map<>.
From your question I gather that you don't need a notion of a next or previous mapping, your mapping pairs are essentially unrelated. In this case, std::unordered_map<> is simply faster than std::map<> because it uses a hash table internally. No matter how big your std::unordered_map<> gets, looking up its elements takes a constant amount of time. This is not true for std::map<>.
I have two integer variables i and j and I want to make a function which takes these two variables as its argument and interchanges their contents using xor operator. Now if I make the function to take arguments by value i.e void swap (int x , int y);(with function body same as for the function swap below) then the values are being swapped nicely within the function. But as what I want is the swapping of the values of the variables in the calling function I used passing arguments by reference (and by pointers as well) :
void swap ( int& x , int& y )
{
x^=y^=x^=y;
cout << x<< " " << y << endl ;
}
int main ()
{
int i (1), j (2) ;
swap ( i, j ) ;
cout << i << " " << j << endl ;
}
but neither case showed the correct result !
Why is the swap function not swapping the values on passing arguments by reference or pointers ?
I have two integer variables i and j and I want to make a function
which takes these two variables as its argument and interchanges their
contents using xor operator.
Why?
As you've figured out, you need either to pass pointers to the objects, or to use references.
This:
x^=y^=x^=y;
has undefined behavior, since it modifies the same object twice between sequence points (it does this for both x and y).
The xor trick fails if both objects are the same object; the first xor zeros the object.
If you want to swap two objects, just use a temporary:
int temp = x;
x = y;
y = temp;
It's simple, and it works.
As others have noted, this is a pretty silly optimization (if you can call it that). The problem is the chained use of in-place operators. Broken it into separable statements, it works.
x^=y; // values are X^Y, Y
y^=x; // values are X^Y, X
x^=y; // values are Y, X
Like the others, I would encourage you not to riddle your code with such clarity-killing cleverness unless you have a demonstrable need established by profiling and a demonstrable speedup for doing your bit twiddling hack. (cool site)