In C++ I want to add two 50-digit numbers. I use an array to keep each. It means that I want to add two arrays. My problem is that I want to do this in a function named AddNum()
and pass the result to another function named WriteNum for printing and I don't know how to pass an array returned by one function to another function.
hope that my question was clear enough
thanx all
Don't use arrays. Look up the C++ std::vector class in your text book or help system and use that instead. It will make life much easier for you.
Don't return an array from the addition function - instead make it return void and pass the array for storing the result by reference or pointer. Then you will pass that array to the function for printing.
First of all, if you will be adding a lot of numbers, saving them in arrays is troublesome and takes both cpu power and memory. If you can, use GMP (optimized and fast library).
If you must use arrays, then use c++'s vectors instead of c's arrays which will minimize the chance for error and make it simpler.
To send a vector to a function, you do it normally as with int's, string's etc, namely
vector<int> number1;
vector<int> number2;
addnum(number1, number2);
where addnum is defined as :
void addnum(vector<int> a, vector<int> b)
This will copy the first and the second vector array that you have into variables a and b. It is recommended that you send a reference to the addnum in order skip to copy the vectors all the time. This can be done by changing the addnum definition to :
void addnum(vector<int>& a, vector>int>& b)
and then performing normal operation on a and b as usual.
To have addnum return a vector you need to change the definition of addnum to
vector<int> addnum(vector<int>& a, vector>int>& b)
and of course have the return statement with the vector you want to return.
If you choose to send the values by references, that means that the number1 and number2 vectors declared in you main class will also change if you change them in the addnum function. That basically means that, if you save the result in variable a in the addnum function, you will have that same value in the number1 vector, meaning you don't need the function to return a new vector but can instead reuse the existing ones.
Just to clarify the answer of sharptooth: if you want to return a new array, you have to allocate it in the function and someone else will have to free it. It can be done but you will always have to remember to free the result after calling the function. As Neil Butterworth points out: std::vector helps you solve this.
if i get it right, and if this is what you wanna do, your functions should have signatures like that:
int* addNumbers(int* array1, int* array2)
{
....
}
and
void writeNumbers(int *array3)
{
....
}
and you can call it like:
//declare and init array1 and array2
//...
writeNumbers(addNumbers(array1, array2));
i hope i understood your question correctly.
Related
So for the past 4 months i've been learning C++ and I made lots of progress, actually getting very close to learning graphs soon.
There's just one thing that I still have problems and and I just don't get it, and that is the variables on a function.
Basically I do not know what kind of variables to put inside the () of a function in the beginning, and what variables I need to put after.
I know it depends on the exercise, so i'll try to give an example.
so I want to calculate the sum of a and b in a function.
int calculateSum(int a, int b){
int sum;
}
so why do I put under the function and not inside the parenthesis?
why can't it just be like:
int calculateSum(int a, int b, int sum){
//code
}
Variables inside the () are the parameters of your function. That is, the inputs it expects when it is called from other code. The variables inside the {} are for use exclusively inside your function.
Your first example makes sense - you'd use it something like this:
int answer = calculateSum(1, 2);
What would you pass as an argument for the sum parameter in your second example? It's sort of a meaningless request - the caller of your function wants to get the sum back from your routine.
In reality everything depends on the definition of the function. For example we can define a function as follows.
int CalculateSum (int a, int b, int sum);
This function necessarily receives three integers a, b and sum.
The body of the function can be defined
for example like this:
int CalculateSum (int a, int b, int sum) {
sum = a + b;
return sum;
}
We can also define the function as well.
int CalculateSum (int a, int b);
This function receives two integers a and b.
the body of the function can be
int CalculateSum (int a, int b) {
int sum;
sum = a + b;
return sum;
}
If you are the creator of the function you can do it however you want, but if the function is already defined you will have to use it as the definition begins.
When you write a function, you need to split your mind into two different personas. You have the developer who's writing the function, we'll call them FuncDev, and you have the developer who will be calling that function, we'll call them CallDev.
When FuncDev is writing the function, they need to think about what CallDev needs the function to do and in what situations they'll be calling it. What information does CallDev have when they're calling the function? What do they want the function to actually do or give back?
In the case of calculateSum, CallDev is going to have two numbers that they want to find the sum of. And FuncDev only needs two numbers to correctly calculate a sum. So everyone's in agreement here: to call calculateSum, you should provide two numbers and get a number back (that's the sum of those two).
All of this information can be found in the function header:
//- This function will return (or give back) an integer
//| - This function requires two integers to do its job
//v v
int calculateSum(int a, int b) {
You don't need to also include an int sum parameter because A. that's not something CallDev will have at the time of calling the function. The whole point they're calling is to get a sum in the first place! And B. that's not something FuncDev needs to calculate the sum. So you'd be imposing an extra condition on anyone calling the function without gaining anything in the function implementation.
Also, everything that happens inside the curly braces in the function logic itself, CallDev should never need to know about. Whether FuncDev decides to make a int sum variable to hold the sum before they return it, etc... shouldn't matter.
Usually, when I'm developing, I'll make the function calls before I even write the functions. So in your case, I may be going along and think "Hmm, I really need the sum of two numbers here. I have two numbers onhand, it'd be nice if I could just call calculateSum(num1, num2) and get the value I need." So I'll actually just write the call to the function and keep going1.
1. In actuality, this looks like writing tests when applicable for the function and then writing it. But the premise is the same. I'm defining the behavior, inputs and outputs of the function all before I write it.
So I am making a program in C++ and my main method has to construct an object that takes as a parameter a vector.
This is my code:
int main() {
vector<Seller> *staff = new vector<Seller>;
for (int i = 0; i < 50; i++) {
staff->push_back(Seller(i));
}
BookStore store(*staff);
deque<Book> books;
books = store.getBooks();
}
So, these are some pretty simple Object-Oriented concepts I think.
My goals are:
First, initializing an empty vector of sellers. A Seller is an object that has a constructor:
Seller(int i);
And represents, of course, a seller.
Then, I want to fill in the vector with actual Sellers. These are constructed in the for loop.
Then, I want to create a Store, which takes as an argument the sellers that work there.
Finally, I create a new deque called books, and I assign to it the value of books in the Store class. The initialisation of the Books deque is done in the constructor of the Store:
Store::Store(vector<Seller> &sellers) {
this->sellers = sellers;
this->books = deque<Book> (100, "Harry Potter");
}
So this is the code and I am wondering if I am making a mistake in the passing arguments to new constructors part.
I am a bit confused when passing by reference so I am asking for a bit on help on that part. I have two main questions:
1) Are there any errors there, considering how I want to run my program? Consider also that in the rest of the main method (not included here) I constantly change the value of the books deque.
2) Is there any way to replace an element in a deque without having to erase and insert?
Is there a built-in function replace? If not, is the below code going to work if I just want to replace a value in the deque?
For example, if the deque is like that:
3 4 5 2
And it (an iterator) has value 2.
Then I want the deque to become:
3 4 6 2
When doing:
books.erase(it);
books.insert(it, 6);
Thanks for any tips or help!
OK, here a short analysis.
Firstly, the unique real error I found: staff is defined as a pointer and is given a value with new but is never released. You should anyway avoid using raw pointers, so either create the object on the stack:
vector<Seller> staff{};
or use a smart pointer
auto staff = make_unique<vector<Seller>>{};
(you will then have to learn something about the ownership semantics, so as you still are a beginner I'd recommend the first solution).
Then, notice how the line
this->sellers = sellers;
in Store::Store will make a copy of the sellers vector, which probably is not what you meant. If you wanted your store to reference the variable created on main(), you should redefine your Store as
class Store {
// ...
vector<Seller>& sellers;
//...
};
and the constructor as
Store::Store(vector<Seller> &sellers) :
sellers{sellers} // reference member variables must be given a value before the body of the constructor begins
{
books = deque<Book> (100, "Harry Potter");
}
For the same reason, your line
books = store.getBooks();
will make a copy of the deque (but maybe in this case it was intended).
Finally, C++ offers many container manipulating functions under the <algorithms> library. Take a look at the reference. But if you already have an iterator to the element you want to replace, you do not need such algorithms, just write:
*it = 6;
I would like to create a vector (arma::uvec) of integers - I do not ex ante know the size of the vector. I could not find approptiate function in Armadillo documentation, but moreover I was not successfull with creating the vector by a loop. I think the issue is initializing the vector or in keeping track of its length.
arma::uvec foo(arma::vec x){
arma::uvec vect;
int nn=x.size();
vect(0)=1;
int ind=0;
for (int i=0; i<nn; i++){
if ((x(i)>0)){
ind=ind+1;
vect(ind)=i;
}
}
return vect;
}
The error message is: Error: Mat::operator(): index out of bounds.
I would not want to assign 1 to the first element of the vector, but could live with that if necessary.
PS: I would really like to know how to obtain the vector of unknown length by appending, so that I could use it even in more general cases.
Repeatedly appending elements to a vector is a really bad idea from a performance point of view, as it can cause repeated memory reallocations and copies.
There are two main solutions to that.
Set the size of the vector to the theoretical maximum length of your operation (nn in this case), and then use a loop to set some of the values in the vector. You will need to keep a separate counter for the number of set elements in the vector so far. After the loop, take a subvector of the vector, using the .head() function. The advantage here is that there will be only one copy.
An alternative solution is to use two loops, to reduce memory usage. In the first loop work out the final length of the vector. Then set the size of the vector to the final length. In the second loop set the elements in the vector. Obviously using two loops is less efficient than one loop, but it's likely that this is still going to be much faster than appending.
If you still want to be a lazy coder and inefficiently append elements, use the .insert_rows() function.
As a sidenote, your foo(arma::vec x) is already making an unnecessary copy the input vector. Arguments in C++ are by default passed by value, which basically means C++ will make a copy of x before running your function. To avoid this unnecessary copy, change your function to foo(const arma::vec& x), which means take a constant reference to x. The & is critical here.
In addition to mtall's answer, which i agree with,
for a case in which performance wasn't needed i used this:
void uvec_push(arma::uvec & v, unsigned int value) {
arma::uvec av(1);
av.at(0) = value;
v.insert_rows(v.n_rows, av.row(0));
}
I am trying to create a jump table for a fuzzy controller. Basically, I have a lot of functions that take in a string and return a float, and I want to be able to do something along the lines:
float Defuzzify(std::string varName, DefuzzificationMethod defuzz)
{
return functions[defuzz](varName);
}
where DefuzzificationMethod is an enum. The objective is to avoid a switch statement and have a O(1) operation.
What I have right now is:
float CenterOfGravity(std::string varName);
std::vector<std::function<float (std::string)>> defuzzifiers;
Then I try to initialize it in the constructor with:
defuzzifiers.reserve(NUMBER_OF_DEFUZZIFICATION_METHODS);
defuzzifiers[DEFUZZ_COG] = std::bind(&CenterOfGravity, std::placeholders::_1);
This is making the compiler throw about 100 errors about enable_if (which I don't use anywhere, so I assume std does). Is there a way to make this compile ? Moreover, is there a way to make this a static vector, since every fuzzy controller will essentially have the same vector ?
Thanks in advance
Reserve just makes sure there's enough capacity, it doesn't actually mak the vector's size big enough. What you want to do is:
// construct a vector of the correct size
std::vector<std::function<float (std::string)>> defuzzifiers(NUMBER_OF_DEFUZZIFICATION_METHODS);
// now assign into it...
// if CentorOfGravity is a free function, just simple = works
defuzzifiers[DEFUZZ_COG] = CenterOfGravity;
// if it's a method
defuzzifiers[DEFUZZ_COG] = std::bind(&ThisType::CenterOfGravity, this, std::placeholders::_1);
Now this might leave you some holes which don't actually have a function defined, so maybe you want to provide a default function of sorts, which the vector constructor allows too
std::vector<std::function<float (std::string)>> defuzzifiers(
NUMBER_OF_DEFUZZIFICATION_METHODS,
[](std::string x) { return 0f; }
);
An unrelated note, you probably want your functions to take strings by const-ref and not by value, as copying strings is expensive.
Deal all, I have implemented some functions and like to ask some basic thing as I do not have a sound fundamental knowledge on C++. I hope, you all would be kind enough to tell me what should be the good way as I can learn from you. (Please, this is not a homework and i donot have any experts arround me to ask this)
What I did is; I read the input x,y,z, point data (around 3GB data set) from a file and then compute one single value for each point and store inside a vector (result). Then, it will be used in next loop. And then, that vector will not be used anymore and I need to get that memory as it contains huge data set. I think I can do this in two ways.
(1) By just initializing a vector and later by erasing it (see code-1). (2) By allocating a dynamic memory and then later de-allocating it (see code-2). I heard this de-allocation is inefficient as de-allocation again cost memory or maybe I misunderstood.
Q1)
I would like to know what would be the optimized way in terms of memory and efficiency.
Q2)
Also, I would like to know whether function return by reference is a good way of giving output. (Please look at code-3)
code-1
int main(){
//read input data (my_data)
vector<double) result;
for (vector<Position3D>::iterator it=my_data.begin(); it!=my_data.end(); it++){
// do some stuff and calculate a "double" value (say value)
//using each point coordinate
result.push_back(value);
// do some other stuff
//loop over result and use each value for some other stuff
for (int i=0; i<result.size(); i++){
//do some stuff
}
//result will not be used anymore and thus erase data
result.clear()
code-2
int main(){
//read input data
vector<double) *result = new vector<double>;
for (vector<Position3D>::iterator it=my_data.begin(); it!=my_data.end(); it++){
// do some stuff and calculate a "double" value (say value)
//using each point coordinate
result->push_back(value);
// do some other stuff
//loop over result and use each value for some other stuff
for (int i=0; i<result->size(); i++){
//do some stuff
}
//de-allocate memory
delete result;
result = 0;
}
code03
vector<Position3D>& vector<Position3D>::ReturnLabel(VoxelGrid grid, int segment) const
{
vector<Position3D> *points_at_grid_cutting = new vector<Position3D>;
vector<Position3D>::iterator point;
for (point=begin(); point!=end(); point++) {
//do some stuff
}
return (*points_at_grid_cutting);
}
For such huge data sets I would avoid using std containers at all and make use of memory mapped files.
If you prefer to go on with std::vector, use vector::clear() or vector::swap(std::vector()) to free memory allocated.
erase will not free the memory used for the vector. It reduces the size but not the capacity, so the vector still holds enough memory for all those doubles.
The best way to make the memory available again is like your code-1, but let the vector go out of scope:
int main() {
{
vector<double> result;
// populate result
// use results for something
}
// do something else - the memory for the vector has been freed
}
Failing that, the idiomatic way to clear a vector and free the memory is:
vector<double>().swap(result);
This creates an empty temporary vector, then it exchanges the contents of that with result (so result is empty and has a small capacity, while the temporary has all the data and the large capacity). Finally, it destroys the temporary, taking the large buffer with it.
Regarding code03: it's not good style to return a dynamically-allocated object by reference, since it doesn't provide the caller with much of a reminder that they are responsible for freeing it. Often the best thing to do is return a local variable by value:
vector<Position3D> ReturnLabel(VoxelGrid grid, int segment) const
{
vector<Position3D> points_at_grid_cutting;
// do whatever to populate the vector
return points_at_grid_cutting;
}
The reason is that provided the caller uses a call to this function as the initialization for their own vector, then something called "named return value optimization" kicks in, and ensures that although you're returning by value, no copy of the value is made.
A compiler that doesn't implement NRVO is a bad compiler, and will probably have all sorts of other surprising performance failures, but there are some cases where NRVO doesn't apply - most importantly when the value is assigned to a variable by the caller instead of used in initialization. There are three fixes for this:
1) C++11 introduces move semantics, which basically sort it out by ensuring that assignment from a temporary is cheap.
2) In C++03, the caller can play a trick called "swaptimization". Instead of:
vector<Position3D> foo;
// some other use of foo
foo = ReturnLabel();
write:
vector<Position3D> foo;
// some other use of foo
ReturnLabel().swap(foo);
3) You write a function with a more complicated signature, such as taking a vector by non-const reference and filling the values into that, or taking an OutputIterator as a template parameter. The latter also provides the caller with more flexibility, since they need not use a vector to store the results, they could use some other container, or even process them one at a time without storing the whole lot at once.
Your code seems like the computed value from the first loop is only used context-insensitively in the second loop. In other words, once you have computed the double value in the first loop, you could act immediately on it, without any need to store all values at once.
If that's the case, you should implement it that way. No worries about large allocations, storage or anything. Better cache performance. Happiness.
vector<double) result;
for (vector<Position3D>::iterator it=my_data.begin(); it!=my_data.end(); it++){
// do some stuff and calculate a "double" value (say value)
//using each point coordinate
result.push_back(value);
If the "result" vector will end up having thousands of values, this will result in many reallocations. It would be best if you initialize it with a large enough capacity to store, or use the reserve function :
vector<double) result (someSuitableNumber,0.0);
This will reduce the number of reallocation, and possible optimize your code further.
Also I would write : vector<Position3D>& vector<Position3D>::ReturnLabel(VoxelGrid grid, int segment) const
Like this :
void vector<Position3D>::ReturnLabel(VoxelGrid grid, int segment, vector<Position3D> & myVec_out) const //myVec_out is populated inside func
Your idea of returning a reference is correct, since you want to avoid copying.
`Destructors in C++ must not fail, therefore deallocation does not allocate memory, because memory can't be allocated with the no-throw guarantee.
Apart: Instead of looping multiple times, it is probably better if you do the operations in an integrated manner, i.e. instead of loading the whole dataset, then reducing the whole dataset, just read in the points one by one, and apply the reduction directly, i.e. instead of
load_my_data()
for_each (p : my_data)
result.push_back(p)
for_each (p : result)
reduction.push_back (reduce (p))
Just do
file f ("file")
while (f)
Point p = read_point (f)
reduction.push_back (reduce (p))
If you don't need to store those reductions, simply output them sequentially
file f ("file")
while (f)
Point p = read_point (f)
cout << reduce (p)
code-1 will work fine and is almost the same as code-2, with no major advantages or disadvantages.
code03 Somebody else should answer that but i believe the difference between a pointer and a reference in this case would be marginal, I do prefer pointers though.
That being said, I think you might be approaching the optimization from the wrong angle. Do you really need all points to compute the output of a point in your first loop? Or can you rewrite your algorithm to read only one point, compute the value as you would in your first loop and then use it immediately the way you want to? Maybe not with single Points, but with batches of points. That could potentially cut back on your memory require quite a bit with only a small increase in processing time.