Iteration to create variables - c++

I was just curious to know if there is way to create a new variable with a new name every time a loop is executed.
For example:
#include <iostream>
int main()
{
for (int x = 1 ; x<=5 ; x++)
int a_x;
return 0;
}
5 new variables should be created with names a_1, a_2, ..., a_5
The above code just shows what I am looking for and is not the answer.
Is this possible without using arrays?

No, there is no way to do what you've outlined (directly). Here are several possible alternatives:
First off, if you do not need the "variables" to be accessible outside the loop, just use a normal local variable:
for (int x = 1; x <= 5; ++x) {
int a = whatever; // This will be freshly redeclared & reinitialised in each iteration
}
If the bounds of the iteration are known at compile time, you can use an array:
std::array<int, 5> a;
for (int x = 0; x < a.size(); ++x) {
a[x];
}
If the bounds are only known at runtime, use a dynamic array:
std::vector<int> a(the_runtime_size);
for (int x = 0; x < a.size(); ++x) {
a[x];
}
If you really need individual variables for some reason (and you know the number at compile time), you could resort to preprocessor tricks with Boost.Preprocessor. But that is far above beginner level:
#include <boost/preprocessor>
#define DECLARE_MY_VARIABLE(z, idx, name) \
int BOOST_PP_CAT(name, BOOST_PP_CAT(_, idx));
BOOST_PP_REPEAT(5, DECLARE_MY_VARIABLE, a)
The code above will expand to:
int a_0; int a_1; int a_2; int a_3; int a_4;
You could of course take this several steps further, to have each of the variables of a different type, or name them by names instead of by indices. It will just require more macro magic.
Disclaimer: Do NOT use this approach unless you very clearly know you need it. Even then, reconsider twice before you actually do that. And if you still do, document it heavily. Stuff like this should generally be hidden deep inside a library under a nice & clean user-friendly interface.

No you can't do that in C++.
The best thing to do in this case would be to create an array of ints and use the for loop to populate them.
int a_x[5];
for (int x = 1 ; x<=5 ; x++)
a_x[x - 1] = /*ToDo - something*/
Note that
arrays are zero-based: can you see how I've used x - 1. The normal thing to do would be to rebase x in the for loop though: for (int x = 0 ; x < 5; ...
arrays are not initialised. You must populate the contents.

While many will assume that this is impossible, it can be achieved with the preprocessor. It is necessary that the loop count is known at compile time. Here I use the Boost Preprocessor Library. The example for PP_REPEAT does almost exactly what you want.
#include <boost/preprocessor/repetition/repeat.hpp>
#define DECL(z, n, text) text ## n = n;
int main()
{
BOOST_PP_REPEAT(5, DECL, int a_) // expands to int a_0 = 0; int a_1 = 1; ...
return 0;
}
Please remember: this is certainly not what you want. You probably want to use an array. Do only use this if you are absolutely certain that you need it.

Related

Create Dynamically Allocated Array C++

I'm trying to create a dynamically allocated array of type unsigned char* in C++. However, when I this I get back a string instead of a bracket enclosed ({}) array which is what I want.
unsigned char* arr = new unsigned char[arrLen];
Code Picture
Picture showing the difference between the two
You see how the latter doesn't just go to nothing after the first character? That's what I want.
How might I go about remedying this?
Thank you for your time.
First, de debugger assumes by default that char represents an ascii character rather than a number. It will display char as such.
arr2 has type const char[3] so the debugger knows there are 3 elements to display.
arr has type const char*. The debugger can't know if it's only one elements or an array with a certain number of elements.
If you are using visual studio for instance, you can hint the debugger to display three char by adding a “variable watch” with the syntax arr,3 in the watch menu.
I'm not sure if this is what you are looking for, but have you tried using a std::vector? It can handle the dynamic assignment you are looking for at least, and shouldn't treat a NULL character as the end of a string.
#include <vector>
std::vector<char> arr = { 0x5A, 0x00, 0x2B };
If you want a list of chars(array) that grows dynamically, what you need is a list of pointers where the list of each segment is a large number-say 1000. A vector container class sacrifices memory usage for the ability to grow.
vector container class allows for dynamic growth but uses a lot of memory
Also, dynamic growth one data element at a time is not recommended for a large list of data. If you want dynamic growth for a large list, create a list in chunks such as the following. Use a large list segment- of say 1000 units. I created 1000 lists in the following example. I do this by creating an array of 1000 pointers. This will create the 1 million chars you are looking for and can grow dynamically. The following example shows how you would do this.
.
void main() {
unsigned char* listsegment[1000];
int chrn=0;
int x, y = 0;
for (int x = 0; x < 1000; x++) {
listsegment[x] = new unsigned char[1000];
for (y = 0; y < 1000; y++) {
*(listsegment[x] + y) = chrn;
if (chrn >=255) chrn=0;
else chrn++;
}
}
}
Completing the program- What if more than 1000 segments need to be dynamically allocated?
Then create a list of Segment Sets. It can either be in a linked list or a in a container class.
Since the single set creates a 1000 segments of 1000 characters, a collection of these sets needs probably not be larger than 1000. A thousands sets would equal (1000*1000)*1000 which would equal one billion. Therefore, the collection would only need to be 1000 or less, which can be quickly iterated through-which makes random access for the collection not necessary.
Here is the program redone to support an infinite amount of sets through an infinitely large collection of sets. This also is a good example of segmented dynamic memory allocation in general.
#include <iostream>
#include<queue>
using namespace std;
struct listSegmentSetType {
unsigned char* listSegment[1000];
int count=0;
};
void main() {
listSegmentSetType listSegmentSet;
queue<listSegmentSetType> listSegmentSetCollection;
int numberOfListSegmentSets = 0;
int chrn = 0;
int x, y = 0;
listSegmentSet.count = 0;
for (int x = 0; x < 1000; x++) {
listSegmentSet.listSegment[x] = new unsigned char[1000];
for (y = 0; y < 1000; y++) {
*(listSegmentSet.listSegment[x] + y) = chrn;
if (chrn >= 255) chrn = 0;
else chrn++;
}
listSegmentSet.count++;
}
// add just completely filled out first list segment set to que
listSegmentSetCollection.push(listSegmentSet);
numberOfListSegmentSets++;
// now fill in second set of list segments-
listSegmentSet.count = 0;
for (int x = 0; x < 1000; x++) {
listSegmentSet.listSegment[x] = new unsigned char[1000];
for (y = 0; y < 1000; y++) {
*(listSegmentSet.listSegment[x] + y) = chrn;
if (chrn >= 255) chrn = 0;
else chrn++;
}
listSegmentSet.count++;
}
listSegmentSetCollection.push(listSegmentSet);
numberOfListSegmentSets++;
// now fill out any more sets of list segments and add to collection
// only when count listSegmentSet.count is no
// longer less than 1000.
}

modifying values in pointers is very slow?

I'm working with a huge amount of data stored in an array, and am trying to optimize the amount of time it takes to access and modify it. I'm using Window, c++ and VS2015 (Release mode).
I ran some tests and don't really understand the results I'm getting, so I would love some help optimizing my code.
First, let's say I have the following class:
class foo
{
public:
int x;
foo()
{
x = 0;
}
void inc()
{
x++;
}
int X()
{
return x;
}
void addX(int &_x)
{
_x++;
}
};
I start by initializing 10 million pointers to instances of that class into a std::vector of the same size.
#include <vector>
int count = 10000000;
std::vector<foo*> fooArr;
fooArr.resize(count);
for (int i = 0; i < count; i++)
{
fooArr[i] = new foo();
}
When I run the following code, and profile the amount of time it takes to complete, it takes approximately 350ms (which, for my purposes, is far too slow):
for (int i = 0; i < count; i++)
{
fooArr[i]->inc(); //increment all elements
}
To test how long it takes to increment an integer that many times, I tried:
int x = 0;
for (int i = 0; i < count; i++)
{
x++;
}
Which returns in <1ms.
I thought maybe the number of integers being changed was the problem, but the following code still takes 250ms, so I don't think it's that:
for (int i = 0; i < count; i++)
{
fooArr[0]->inc(); //only increment first element
}
I thought maybe the array index access itself was the bottleneck, but the following code takes <1ms to complete:
int x;
for (int i = 0; i < count; i++)
{
x = fooArr[i]->X(); //set x
}
I thought maybe the compiler was doing some hidden optimizations on the loop itself for the last example (since the value of x will be the same during each iteration of the loop, so maybe the compiler skips unnecessary iterations?). So I tried the following, and it takes 350ms to complete:
int x;
for (int i = 0; i < count; i++)
{
fooArr[i]->addX(x); //increment x inside foo function
}
So that one was slow again, but maybe only because I'm incrementing an integer with a pointer again.
I tried the following too, and it returns in 350ms as well:
for (int i = 0; i < count; i++)
{
fooArr[i]->x++;
}
So am I stuck here? Is ~350ms the absolute fastest that I can increment an integer, inside of 10million pointers in a vector? Or am I missing some obvious thing? I experimented with multithreading (giving each thread a different chunk of the array to increment) and that actually took longer once I started using enough threads. Maybe that was due to some other obvious thing I'm missing, so for now I'd like to stay away from multithreading to keep things simple.
I'm open to trying containers other than a vector too, if it speeds things up, but whatever container I end up using, I need to be able to easily resize it, remove elements, etc.
I'm fairly new to c++ so any help would be appreciated!
Let's look from the CPU point of view.
Incrementing an integer means I have it in a CPU register and just increments it. This is the fastest option.
I'm given an address (vector->member) and I must copy it to a register, increment, and copy the result back to the address. Worst: My CPU cache is filled with vector pointers, not with vector-member pointers. Too few hits, too much cache "refueling".
If I could manage to have all those members just in a vector, CPU cache hits would be much more frequent.
Try the following:
int count = 10000000;
std::vector<foo> fooArr;
fooArr.resize(count, foo());
for (auto it= fooArr.begin(); it != fooArr.end(); ++it) {
it->inc();
}
The new is killing you and actually you don't need it because resize inserts elements at the end if the size it's greater (check the docs: std::vector::resize)
And the other thing it's about using pointers which IMHO should be avoided until the last moment and it's uneccesary in this case. The performance should be a little bit faster in this case since you get better locality of your references (see cache locality). If they were polymorphic or something more complicated it might be different.

How to use variable this way c++

Im making a c++ program wherein there are multiple variables for example:
var1, var2, var3, var4;
i want to use it for a for loop like:
for(int x; x<=5; x++){
if(var1==1){cout << "hi";}
}
But instead of typing var1 i want to make it var"x" where x is equal to 1.
I remember from my batch programming days(not exact) i can use this like:
set x=1
echo var%x%
then the output will be var1.
You can do this, using macros, but I really don't think it is a good idea. Why not use arrays instead? With arrays you can reference the index you want, so instead of var1, var2, var3, ... it will be var[0], var[1], var[2], ... Much more C++ like, anyway.
When using arrays, I would even recommend thinking in one of the container classes C++ offers, such as std::vector, or std::array. To have a simple array of integer variables in a vector, simply declare one such as: std::vector<int> intVec, to extract a specific element use the at function, such as intVec.at(0) which will extract the first element. Really use, almost any other approach, than macros.
Having said that, to do it in a macro you would need to make a macro like this:
#define var(x) var##x
var(1) = 2; // resolves to var1 = 2;
Macros are compile time however, so using them in a loop, by passing a variable to it, will not work the way you would expect. So calling int x = 1; var(x) = 2; would not set var1 to 2, but rather attempt to set varx to 2.
The macro solution comes with a number of disadvantages, one is making your less readable, another is making your code more error prone, and lastly, why stir away from the "C++ way"?
You can make use of command line arguments while invoking your program executable.
prog.exe 3 4 1 6
This way your program will receive 5 command line arguments, the first being the program name itself.
The code will look something like this:
int main(int argc, char *argv[]) {
// For the above example, argc = 5
for (int i = 1; i < argc; ++i) {
// make use of argv[i]
}
}
This may not be exactly what you want to do, but confirms to your idea of multiple variables var1 i.e. argv[1]
It is possible to this in many script programming but unfortunately no direct support is available in C++.
Some ways around are use of arrays (if possible) or an array of pointers to actual variables.
int vars[5] = {...};
for(int x = 0; x < 5; x++){
if(var[x]==1){cout << "hi";}
}
or
int var0 = 2, var1 = 42, var2 = 7;
int *const pvars[] = {&var0, &var1, &var2};
for(int x = 0; x < 3; x++) {
if(*(pvars[x]) == 1)
{
cout << "hi";
}
}
or as mentioned in this comment
int var0 = 2, var1 = 42, var2 = 7;
for(auto &var = {var0, var1, var2}) {
if(var == 1)
{
cout << "hi";
}
}

better way to shrink copy/paste codes

Currently I have this trunk of code: a vector of structs v[myStruct]. The size of it is 3. I named these structs as myStruct_A, myStruct_B, and myStruct_C. Each piece of code is almost same, but with its name as suffix.
SomeMap someMap_A;
for (auto& pair : myStruct_A.hashMap) {
SomeStruct someStruct = foo(pair);
someMap_A[someStruct.key] = someStruct.value;
anotherStruct_A[someStruct.nameX] = someStruct.bundle;
}
someVector.push_back[someMap_A];
All of the three A,B,C need do the above things. The question here is that if using a function, I don't know how to separate and specify the names. I need get several vectors of data which are based on all of those three myStructs' outputs.
You can do this with a macro. For example, here's a simplified version:
#define process(i, suffix) some_vect_ ## suffix.push_back(i); \
some_set_ ## suffix.insert(i);
int main() {
std::vector<int> some_vect_A, some_vect_B, some_vect_C;
std::set<int> some_set_A, some_set_B, some_set_C;
for (int i = 0; i < 100; i++) {
int val = rand();
process(val, A); // adds `val` to `some_vect_A` and `some_set_A`
process(val, B); // adds `val` to `some_vect_B` and `some_set_B`
process(val, C); // adds `val` to `some_vect_C` and `some_set_C`
}
}
This particular demo code is pretty pointless (it produces identical results in all three sets and all three vectors), but does show how to do the manipulation you need.

Simple loop, which one I would get more performance and which one is recommended? defining a variable inside a loop or outside of it?

Variable outside of the loop
int number = 0;
for(int i = 0; i < 10000; i++){
number = 3 * i;
printf("%d",number);
}
or Variable inside of the loop
for(int i = 0; i < 10000; i++){
int number = 3 * i;
printf("%d",number);
}
Which one is recommended and which one is better in performance?
Edit:
This is just an example to exhibit what I mean, All I wanna know is if defining a variable inside a loop and outside a loop means the same thing , or there's a difference.
Time to learn something early: any optimization you could make on something like this will be irrelevant in the face of printf.
Printf will be very, very slow. You could quintuple the math and get no measurable speed decrease. It's just the nature of printing to the terminal.
As for your edited question, there is no difference defining it in the loop or out. Imagine that
for (i = 0; i < 500; i++) {
int a = i * 3;
}
is just the same as
int forloop::a; // This doesn't work, the idea is to show it just changes the scope
for (i = 0; i < 500; i++) {
a = i * 3;
}
They will produce identical code, unless you start needing to use that variable outside of the loop it is defined in, because it is defined in the local scope of the loop. So...more like this:
int forloop::a; // Still not valid code, just trying to show an explanation
namespace forloop {
for (i = 0; i < 500; i++) {
a = i * 3;
}
} // namespace forloop
If this is unclear please let me know I'll go into more detail or explain differently.
Do not bother you with performance at first: make it safe before everything.
I would just quote Scott Meyers (Effective C++) for your concern:
"Postpone declarations as far as you can".
Thus, the second pattern is safer.
Example:
int j = 0;
for(int i = 0; i < 10000; i++){
j = 3 * i;
printf("%d",j);
}
...
// Use of j out of control!!!
int k = j * 5;
Now with the second pattern:
for(int i = 0; i < 10000; i++){
int j = 3 * i;
printf("%d",j);
}
...
// j not declared at this point.
// You get informed of the mistake at compile time, which is far much better.
int k = j * 5;
You do have a C++ tag, and you mention "declaring a string" in the question. Therefore there might be a performance difference (and yes, the printf could swamp it). Declaring a non-simple variable means calling a constructor, which might mean a non-trivial amount of work. In that case, declaring it inside of the loop could be hiding significant work in what appears to be an innocent declaration.
In general, the answer is that if you really care about performance - and treating the sample code as only an example of the difference between two places to declare a variable - then for non-simple variables, it is better to declare it outside the loop, unless the semantics require a fresh version of a temporary at each iteration.
There are likely many other places first to look at if performance is an issue, but one consideration is always moving loop invariants out of loops, especially if it is much easier for you to tell that it is invariant than for the compiler. And what looks like a declaration, can, in C++, fall into that category.
If, for (silly) example, you have
int k = 43;
for ( int i = 0; i < N; ++i )
{
int j = 17 + k; // k was previously defined outside the loop, but doesn't change in it
l = j * j; // l was also declared outside the loop
}
any good optimizing compiler can recognize that k is constant, and that j is always assigned 60, and l is assigned 3600 N times, and the loop can simply be removed and replaced with a single assignment to l. Here k and j are both loop invariants.
But a not-quite-so-good compiler might miss even one link in that chain, and wind up creating the loop.
It gets harder for the compiler to figure things out when you have
Foo k( 43 ); // a class that takes an int argument to its constructor
for( int i = 0; i < N; ++i )
{
Bar j( k ); // a Bar takes an int argument, adds 17 and stores it.
l = j.squared();
}
Same invariants. Not as easy to detect without looking inside the workings of bar; and if the constructor and squared method aren't inline, we've just made it slower.
In this case, printf("%d", i * 3) would be better than defining the variable at all.
To answer your question and not nitpicking:
The difference between the 2 variants is, that you are declaring your variable number in different "variable environments" - by which I mean that the scope changes. A variable environment is given by your curly braces { ... }. Everytime you open a new curly brace like this { ... { ... } ... }, you declare a new variable environment inside the old one, which means, that if you declare numbers like so:
{ ... { int numbers; ... } ... }
this variable will only be visible or existent in the innermost environment. So
{ ... { int numbers; ... } ... do_something(numbers); ... }
will give a compiler error.
And to your concerns about performance: Neither variant is better performing. Most, if not all compilers will give the same assembly.