Question about the efficiency of using an array or individual variables

  • Thread starter yungman
  • Start date
  • #1
4,943
110
I have two questions here. In the program, I have two different boolean expressions, one using array A[10], the other just using individual variablesB(0..9). They both do the same thing as in the program. My question which one is faster in real life hardware? My guess is B(0..9) is faster even though it looks stupid. I think each variable use individual address, so it's one step access. The one using array has to take the starting address, add the index to get the address before accessing the value. I put a lot more emphasis on efficiency than make the code looks "nice".

Also, in the process of declaring the bool A[10], I found out I had to initialize with {1, 1, 1, 1, 1, 1, 1, 1, 1, 1} INSTEAD of {1} for all 10 elements. Why?

C++:
//Efficiency
#include <iostream>
using namespace std;

int main()
{
    bool A[10] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
    bool B0 = true, B1 = true, B2 = true, B3 = true, B4 = true, B5 = true,
        B6 = true, B7 = true, B8 = true, B9 = true;
    bool An, Bn; // result of AND

    An = A[0] && A[1] && A[2] && A[3] && A[4] && A[5] && A[6] && A[7] && A[8] && A[9];
    Bn = B0 && B1 && B2 && B3 && B4 && B5 && B6 && B7 && B8 && B9;
    cout << " An = " << An << "    Bn = " << Bn << "\n\n";
    return 0;
}
Thanks
 

Answers and Replies

  • #2
12,082
5,752
This is a hard and implementation dependent question. My guess would be arrays would be faster from a memory caching point of view with prefetch of data for the cache.
 
  • Like
Likes yungman
  • #3
4,943
110
I have another question on array
I just went through the chapter on array, when initialization of an array int A[size]. The size has to be a constant, it cannot be a variable programmed by program later. I even tried to declare const int size = sz; where sz is variable. Still C++ doesn't like it.

The only other way is to use vector(dynamic array) initiated with undersize vector and use push_back to make the size variable and get to the size needed.

Any other suggestion?
 
  • #4
34,149
5,764
I even tried to declare const int size = sz; where sz is variable. Still C++ doesn't like it.
A variable declared as const has to have its value known at compile time. Since sz is a variable, your declaration won't work.
 
  • Like
Likes yungman
  • #5
4,943
110
A variable declared as const has to have its value known at compile time. Since sz is a variable, your declaration won't work.
Yeh, it's one thing to learn and write the notes, it's when the rubber hits the road by writing a complete program that one really see the details and the limitations. That's why I am NOT following the book on all the search and sorts, I read the flow and logic to understand what they are trying to do, the method, but I then close the book, just get the question and write totally on my own. I am doing the bubble sort right now, I need an array of boolean to keep track of the steps of comparisons. Then I realize the limitations of using array. I have to use vector now in order to leave the choice for user input the number of numbers for sorting. The example of the book use a fixed array of numbers, that's too easy. I want user to be able to enter the amount of numbers as they want and sort.

It's fun to actually write a complete program.
 
  • #6
34,149
5,764
Also, in the process of declaring the bool A[10], I found out I had to initialize with {1, 1, 1, 1, 1, 1, 1, 1, 1, 1} INSTEAD of {1} for all 10 elements. Why?
If you declare you array this way, bool A[10] = {1};, the 0-index element is initialized to 1, and the other 9 are initialized to 0. If you want all of the elements to be 1, you have to supply an initializer list that does this. (Or you could assign values to the array in a for loop.)
This is a hard and implementation dependent question. My guess would be arrays would be faster from a memory caching point of view with prefetch of data for the cache.
I would say the opposite -- that accessing a scalar variable is faster than accessing an array element. With an array element, the run time has to calculate the address of the array element, based on the starting address of the array, to which is added the offset to the element in question. With a scalar variable, the run time merely needs to access the memory address to get the value.

Edit:
On an x86 Windows machine, here is what the Visual Studio C++ compiler generates. All variables are of type int.
First, a scalar variable is accessed and its value is assigned to variable, x.
Code:
// x = num;
mov eax, dword ptr[num]
mov dword ptr[x], eax
The assembly code above copies the value in num to the EAX register, and then copies it to the variable x.

Next, an element of an array is accessed, and its value is assigned to a variable, y.
Code:
// y = Arr[3]
mov eax, 4
imul ecx, eax, 3
mov edx, dword ptr Arr[ecx]
mov dword ptr [y], edx
The first two lines of assembly set the EAX register to 4 (the size of an int), and then multiply it by 3 (the index in the array), storing the value 12 in the ECX register. The number we're looking for is at an offset of 12 bytes from the beginning of the array. The last two lines copy the value at that location to the EDX register, and then copy it to the variable y.
 
Last edited:
  • Like
Likes sysprog
  • #7
34,149
5,764
Then I realize the limitations of using array. I have to use vector now in order to leave the choice for user input the number of numbers for sorting. The example of the book use a fixed array of numbers, that's too easy. I want user to be able to enter the amount of numbers as they want and sort.

It's fun to actually write a complete program.
The arrays your are using are allocated at compile time on the stack. If you want to use an array that is allocated dynamically at run time, or whatever size the user wants, you can do that in C using malloc(), or in C++ using the new operator in its array form.

These are probably a bit ahead of where you are in the book.
 
  • Like
Likes .Scott
  • #8
4,943
110
The arrays your are using are allocated at compile time on the stack. If you want to use an array that is allocated dynamically at run time, or whatever size the user wants, you can do that in C using malloc(), or in C++ using the new operator in its array form.

These are probably a bit ahead of where you are in the book.
No, I have not learn that. I'll wait.

I already experimented using vector and I can do it using vector. But I have a more pressing question now.

In normal situation when we use cin or cin.get, we enter a number, then we have to hit ENTER. If I want to enter any number of integers as I want and want to stop whenever I want, I don't know how to make it easier.

Right now, I can ask user to enter a number, hit enter. Then I ask user to hit any key to enter another number or hit ENTER to quit. But that's a lot of trouble as you enter a number then hit enter, then hit any key follow by enter to repeat. So it takes 4 steps to enter one number as shown in the program:
C++:
//Efficiency
#include <iostream>
#include <vector>
using namespace std;

int main()
{
    vector<int> Av;
    int num;
    char key = 'A';
    while (key != '\n')
    {
        cout << " Enter an integer to be store in the dynamic array Av "; cin >> num;
        Av.push_back(num);
        cout << "\n\n Hit any key to enter another integer, hit ENTER to quit ";
        cin.ignore(255, '\n');
        cin.get(key);
    }
    int x = Av.size();
    cout << " You enter these number into dynamic array Av\n\n";
    cout << " {";
    for (int i = 0; i < x; i++)
        cout << Av[i] << " ";
    cout << "} \n\n";
    return 0;
}
Is there any way to simplify that? Something like number1-spacebar-number2-spacebar.........until hit enter to quit? I just want to make it easier to enter numbers. I am sure the chapters I studied so far don't have anything like this.

Thanks
 
  • #9
370
219
I have two questions here. In the program, I have two different boolean expressions, one using array A[10], the other just using individual variablesB(0..9). They both do the same thing as in the program. My question which one is faster in real life hardware? My guess is B(0..9) is faster even though it looks stupid. I think each variable use individual address, so it's one step access. The one using array has to take the starting address, add the index to get the address before accessing the value. I put a lot more emphasis on efficiency than make the code looks "nice".

Also, in the process of declaring the bool A[10], I found out I had to initialize with {1, 1, 1, 1, 1, 1, 1, 1, 1, 1} INSTEAD of {1} for all 10 elements. Why?

C++:
//Efficiency
#include <iostream>
using namespace std;

int main()
{
    bool A[10] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
    bool B0 = true, B1 = true, B2 = true, B3 = true, B4 = true, B5 = true,
        B6 = true, B7 = true, B8 = true, B9 = true;
    bool An, Bn; // result of AND

    An = A[0] && A[1] && A[2] && A[3] && A[4] && A[5] && A[6] && A[7] && A[8] && A[9];
    Bn = B0 && B1 && B2 && B3 && B4 && B5 && B6 && B7 && B8 && B9;
    cout << " An = " << An << "    Bn = " << Bn << "\n\n";
    return 0;
}
Thanks
Hi Yungman, I am writing you from the future, to warn you to watch out for std::vector< bool >. It isn't what it appears to be.
 
  • Like
  • Haha
Likes sysprog, pbuk and jedishrfu
  • #10
34,149
5,764
Right now, I can ask user to enter a number, hit enter. Then I ask user to hit any key to enter another number or hit ENTER to quit. But that's a lot of trouble as you enter a number then hit enter, then hit any key follow by enter to repeat. So it takes 4 steps to enter one number as shown in the program:
It's a problem when you mix different types of input; i.e., numbers for the vector, and characters to signal the loop to stop. Perhaps a better way is to use a sentinel value -- a value that wouldn't be expected for valid input. In the loop below, I'm assuming that valid numbers are positive, so if the user enters a negative number, the input loop exits.

If that's not feasible, you could ask the user how many numbers will be input, and then run the loop that many times.

Some comments:
  1. The user doesn't care that the vector is named Av, or even that you are using a dynamic array. Don't include that extraneous information in the user prompt.
  2. Try to come up with better variable names. Av and x are just about useless, as these names don't convey to the reader (another programmer who is reviewing or maintaining your program).
  3. It's better to use separate using std::xxx statements, rather than bringing in the whole very large std namespace. I gave an example in another thread of what can go wrong. It's especially bad practice to put such a statement into a header file.
Here's my version of your code.
C++:
#include <iostream>   
#include <vector>       
using std::cout;
using std::cin;
using std::vector;

int main()
{
    vector<int> List;
    int num;
    
    while (true)
    {
        cout << " Enter a nonnegative integer, or a negative number to quit "; 
        cin >> num;
        if (num < 0) break;
        List.push_back(num);        
    }

    int listSize = List.size();
    cout << " You entered these numbers\n\n";
    cout << " {";
    for (int i = 0; i < listSize; i++)
        cout << List[i] << " ";
    cout << "} \n\n";    
}
 
  • Like
Likes pbuk and yungman
  • #11
4,943
110
Hi Yungman, I am writing you from the future, to warn you to watch out for std::vector< bool >. It isn't what it appears to be.
Can you explain, it's not in the book. Doing a little guessing here, it works!!! Maybe, I am too much ahead of myself, wanting to do too much for what I know.
thanks
 
  • #12
370
219
Can you explain, it's not in the book. Doing a little guessing here, it works!!! Maybe, I am too much ahead of myself, wanting to do too much for what I know.
thanks
In the early days of C++, they wanted to make vector< bool > more memory efficient. A bool is just true or false, so it can be represented with a single bit. So they specialzed vector< bool > so that it doesn't contain actual bools, it contains bits. This violates some rules about what a vector is supposed to be. And note that memory is addressed and operated on by the machine at the resolution of bytes.

Normally, it's safe to write to different vector elements from different threads. But not in this case.

So a parallel for loop like below,

C:
const size_t END = vb.size();
#pragma omp parallel for
for( size_t i = 0; i < END; ++i )
{
    vb[ i ] = something(i);
}
is a bug if vb is a vector<bool>, whereas it would be fine for any other type of vector. I once spent a few days perplexed why my code was giving wrong results, and then learned this was why.

There are some other issues with vector< bool > as well, and you can find a lot of blog posts about them. It's considered by most to have been a mistake to add this kind of special case for vector< bool >, but for backwards compatibility it's a mistake the C++ committee needs to live with. Nowdays, there is std::bitset as well. If you can help it, I think it's best to just treat vector< bool > as depreciated.
 
Last edited:
  • Like
Likes pbuk and yungman
  • #13
4,943
110
In the early days of C++, they wanted to make vector< bool > more memory efficient. A bool is just true or false, so it can be represented with a single bit. So they specialzed vector< bool > so that it doesn't contain actual bools, it contains bits. This violates some rules about what a vector is supposed to be. And note that memory is addressed and operated on by the machine at the resolution of bytes.

Normally, it's safe to write to different vector elements from different threads. But not in this case.

So a parallel for loop like below,

C:
const size_t END = vb.size();
#pragma omp parallel for
for( size_t i = 0; i < END; ++i )
{
    vb[ i ] = something(i);
}
is a bug if vb is a bool, whereas it would be fine for any other type of vector. I once spent a few days perplexed why my code was giving wrong results, and then learned this was why.

There are some other issues with vector< bool > as well, and you can find a lot of blog posts about them. It's considered by most to have been a mistake to add this kind of special case for vector< bool >, but for backwards compatibility it's a mistake the C++ committee needs to live with. Nowdays, there is std::bitset as well. If you can help it, I think it's best to just treat vector< bool > as depreciated.
Thanks for taking the time to explain, bottom line is one cannot write one bit at a time........................


BUT, you might give me a new idea..................If I just use char 'T' for true, 'F' for false or something similar. Something along with this idea:
C++:
//Bytewise logic
#include <iostream>
using namespace std;

int main()
{
    short int a, b, c, d, e, f;
    a = 0x00FF;
    b = 0x0000;
    d = 0x00AA;
    e = 0x0055;

    c = a | b;
    cout << " c = " << c << "\n\n";
    c = a & b;
    cout << " c = " << c << "\n\n";

    f = d ^ e;
    cout << " f = " << f << "\n\n";

    return 0;
}
Idea is if I can find a 1byte char or int and set True=0xFF and False=0x00. I can do AND and OR with that. That, I can simulate a vector of boolean, each 1byte......Hell, if I have to use 2bytes short int, so be it. I can create my "boolean" vector or array.

I need to think about this more.

The reason I need this is because I am writing the bubble sort, I need to keep track each pair whether I have to flip them or not, so I need a parallel vector so I can use the same index to access, and check whether all are true, then I know the sort is complete.

I am doing it my own way, I want to write my own bubble sort BEFORE I even look at the book how they do it. If I keep looking at the book first, I'd never learn.
 
Last edited:
  • #14
370
219
Thanks for taking the time to explain, bottom line is one cannot write one bit at a time........................


BUT, you might give me a new idea..................If I just use char 'T' for true, 'F' for false or something similar. Something along with this idea:
C++:
//Bytewise logic
#include <iostream>
using namespace std;

int main()
{
    short int a, b, c, d, e, f;
    a = 0x00FF;
    b = 0x0000;
    d = 0x00AA;
    e = 0x0055;

    c = a | b;
    cout << " c = " << c << "\n\n";
    c = a & b;
    cout << " c = " << c << "\n\n";

    f = d ^ e;
    cout << " f = " << f << "\n\n";

    return 0;
}
Idea is if I can find a 1byte char or int and set True=0xFF and False=0x00. I can do AND and OR with that. That, I can simulate a vector of boolean, each 1byte......Hell, if I have to use 2bytes short int, so be it. I can create my "boolean" vector or array.

I need to think about this more.

The reason I need this is because I am writing the bubble sort, I need to keep track each pair whether I have to flip them or not, so I need a parallel vector so I can use the same index to access, and check whether all are true, then I know the sort is complete.

I am doing it my own way, I want to write my own bubble sort BEFORE I even look at the book how they do it. If I keep looking at the book first, I'd never learn.
Yeah, for writing in parallel, you might try using a vector of char or uchar instead of bool. Or maybe you could just be careful that more than one thread cannot write to the same byte and use a bitset?

You'll probably be doing sequential programming for quite a while before you have to worry about it. It's only when you have multiple threads where it becomes unsafe.
 
  • #15
1,978
265
Edit:
On an x86 Windows machine, here is what the Visual Studio C++ compiler generates. All variables are of type int.
Next, an element of an array is accessed, and its value is assigned to a variable, y.
Code:
// y = Arr[3]
mov eax, 4
imul ecx, eax, 3
mov edx, dword ptr Arr[ecx]
mov dword ptr [y], edx
The first two lines of assembly set the EAX register to 4 (the size of an int), and then multiply it by 3 (the index in the array), storing the value 12 in the ECX register. The number we're looking for is at an offset of 12 bytes from the beginning of the array. The last two lines copy the value at that location to the EDX register, and then copy it to the variable y.
This is in debug mode. in release mode, you get just:
Code:
//static array, the compiler can compute the adress of Arr[3] at compile time.
 move edx, [Arr + 12] for a static array
move [y], edx 
//array on the stack. The data will be at a known offset from ebp 
//ebp = previous value of the stack pointer, used for all local variables and parameters.
move edx, [ebp + offset] 
move [y], edx
And there is no difference between an array, and ordinary local variables
 
  • Like
Likes pbuk
  • #16
34,149
5,764
This is in debug mode.
And there is no difference between an array, and ordinary local variables
I'll have to take your word for this. If I compile in Release mode in VS, the debugger shows only some of the assembly code that is generated.
 
  • #17
1,978
265
I'll have to take your word for this. If I compile in Release mode in VS, the debugger shows only some of the assembly code that is generated.
The code was probably optimized away. It's not uncommon to see your entire test program optimized into
Code:
mov eax, 0
ret
you could make the declaration of the array volatile
volatile int arr[10];
that should keep the compiler from optimizing code that uses the array.

You should be able to see all the disassembly that's actually generated and let the debugger step through it.
 
  • #18
4,943
110
In the early days of C++, they wanted to make vector< bool > more memory efficient. A bool is just true or false, so it can be represented with a single bit. So they specialzed vector< bool > so that it doesn't contain actual bools, it contains bits. This violates some rules about what a vector is supposed to be. And note that memory is addressed and operated on by the machine at the resolution of bytes.

Normally, it's safe to write to different vector elements from different threads. But not in this case.

So a parallel for loop like below,

C:
const size_t END = vb.size();
#pragma omp parallel for
for( size_t i = 0; i < END; ++i )
{
    vb[ i ] = something(i);
}
is a bug if vb is a vector<bool>, whereas it would be fine for any other type of vector. I once spent a few days perplexed why my code was giving wrong results, and then learned this was why.

There are some other issues with vector< bool > as well, and you can find a lot of blog posts about them. It's considered by most to have been a mistake to add this kind of special case for vector< bool >, but for backwards compatibility it's a mistake the C++ committee needs to live with. Nowdays, there is std::bitset as well. If you can help it, I think it's best to just treat vector< bool > as depreciated.
Actually from your response, I came up with this to achieve taking a boolean input and store in a vector of programmable length and perform AND function ( I can do others also, but that's what I need). basically I use a vector <short int>, store 0x00FF for true, 0x0000 for false. I can perform boolean as shown:

C++:
//Bytewise logic
#include <iostream>
#include <vector>
using namespace std;

int main()
{
    vector<short int> Bo;
    int i = 0, index=0, andF; 
    char temp, temp1 ;
    cout << " This program creates a vector of boolean and AND them together\n\n";
    do
    {
        cout << " Enter t for True, f for False and any other key to quit "; cin >> temp;
        if (temp == 't')        Bo.push_back(0x00FF);
        else if (temp == 'f')    Bo.push_back(0x0000);
    } while ((temp == 't') || (temp == 'f'));

    cout << " You entered " << Bo.size() << " elements\n\n";
    index = Bo.size() - 1;
    cout << " You entered {";
    for (int i = 0; i <= index; i++)
    {
        if (temp1 = 't') Bo[i] == 0x00FF;
        else if (temp1 = 'f') Bo[i] == 0x0000;
        cout << temp1 << " ";
    }
    cout << "}\n\n";
    for (int j = 0; j <= index; j++)
        cout << Bo[j] << " ";
    cout << "}\n\n";
    cout << " Index = " << index << "\n\n";
    i = 0;
    do //AND all the elements together
    {
        andF = Bo[i] & Bo[i+1];
        Bo[i + 1] = andF;
        i++;
        cout << " i = " << i << ",  Bo[" << i << "] = " << Bo[i] << ",  andF = " << andF << "\n\n";
    } while (i < index);
    cout << " The result of all the elements of Bo AND together is " << andF << "\n\n";
    return 0;
}
 
  • #19
370
219
Actually from your response, I came up with this to achieve taking a boolean input and store in a vector of programmable length and perform AND function ( I can do others also, but that's what I need). basically I use a vector <short int>, store 0x00FF for true, 0x0000 for false. I can perform boolean as shown:

C++:
//Bytewise logic
#include <iostream>
#include <vector>
using namespace std;

int main()
{
    vector<short int> Bo;
    int i = 0, index=0, andF;
    char temp, temp1 ;
    cout << " This program creates a vector of boolean and AND them together\n\n";
    do
    {
        cout << " Enter t for True, f for False and any other key to quit "; cin >> temp;
        if (temp == 't')        Bo.push_back(0x00FF);
        else if (temp == 'f')    Bo.push_back(0x0000);
    } while ((temp == 't') || (temp == 'f'));

    cout << " You entered " << Bo.size() << " elements\n\n";
    index = Bo.size() - 1;
    cout << " You entered {";
    for (int i = 0; i <= index; i++)
    {
        if (temp1 = 't') Bo[i] == 0x00FF;
        else if (temp1 = 'f') Bo[i] == 0x0000;
        cout << temp1 << " ";
    }
    cout << "}\n\n";
    for (int j = 0; j <= index; j++)
        cout << Bo[j] << " ";
    cout << "}\n\n";
    cout << " Index = " << index << "\n\n";
    i = 0;
    do //AND all the elements together
    {
        andF = Bo[i] & Bo[i+1];
        Bo[i + 1] = andF;
        i++;
        cout << " i = " << i << ",  Bo[" << i << "] = " << Bo[i] << ",  andF = " << andF << "\n\n";
    } while (i < index);
    cout << " The result of all the elements of Bo AND together is " << andF << "\n\n";
    return 0;
}
Why use two bytes instead of one? Also, in C and C++, 0 treated as false, and not zero is treated as true. You can do this for example:

C:
std::vector<uchar> vb;
while( 1 )
{
    char input = getUserInput();
    if(      input == 't' ) vb.push_back( true );
    else if( input == 'f' ) vb.push_back( false );
    else break;
}

if( vb.size() > 1 )
{
    for( size_t i = 1, end = vb.size(); i < end; ++i )
    {
        vb[ i ] = vb[ i ] && vb[ i - 1 ];
    }
    vb[ 0 ] = vb[ 1 ];
}
Also, be careful with code like index = v.size() - 1 You can print out v.size() -1 when v is empty to see what I mean.
 
Last edited:
  • Like
Likes yungman
  • #20
pbuk
Science Advisor
Gold Member
1,670
576
I have quite a lot to say, so here goes:

I have two questions here. In the program, I have two different boolean expressions, one using array A[10], the other just using individual variablesB(0..9). They both do the same thing as in the program. My question which one is faster in real life hardware?
Any sensible compiler on any hardware will pre-compute the address of a[10] and access it just as fast as b10. Actually most modern processors (and certainly any 32+ bit x86) have an instruction that makes accessing a[k] (where k is an integer variable) just as fast as b10.

You should learn about Premature Optimization.

You also need to know (but not now) that if you did need to write faster code you need to stay away from std::vector (and for that matter std::string and the other STL classes) because these do a lot of work behind the scenes managing memory allocation for you. With an array you have to do this yourself.

In summary at this stage in your learning about C++ you need to forget about making your code faster, it's like trying to improve your lap times in a car around a race circuit when you haven't even learned how to change gear (C++ is a race car so it has a clutch and a stick shift).

This is a hard and implementation dependent question. My guess would be arrays would be faster from a memory caching point of view with prefetch of data for the cache.
As was pointed out later in the thread a[10] and b10 compile to the same code so even if there was a hardware level user memory prefetch it wouldn't differentiate between them.

In normal situation when we use cin or cin.get, we enter a number, then we have to hit ENTER. If I want to enter any number of integers as I want and want to stop whenever I want, I don't know how to make it easier.
...
Is there any way to simplify that? Something like number1-spacebar-number2-spacebar.........until hit enter to quit? I just want to make it easier to enter numbers. I am sure the chapters I studied so far don't have anything like this.
Use std::getline, or if you don't want to learn something new use a sentinel value as @Mark44 suggested.

The reason I need this is because I am writing the bubble sort, I need to keep track each pair whether I have to flip them or not, so I need a parallel vector so I can use the same index to access, and check whether all are true, then I know the sort is complete.

I am doing it my own way, I want to write my own bubble sort BEFORE I even look at the book how they do it. If I keep looking at the book first, I'd never learn.
A bubble sort doesn't need a vector to keep track of anything, just a single boolean.

...
I think you can write better code than in this post, and it will make your life (and ours) much easier if you get into the habit of writing code that is easier to read.

C++:
    // Don't use PascalCase for variables, and pick better names (unless 'bo' really
    // does mean something you will remember in 2 years time).
    vector<short int> Bo;

    // Don't leave variables unitialized. Be consistent with your spacing around '='.
    int i = 0, index=0, andF;

    // You must be able to thing of better names than these - and initialize them.
    char temp, temp1 ;

        // Use constants or even macros  something like TRUE_VALUE and FALSE_VALUE
        // instead of typing literal values each time; you should be able to think of two
        // obvious reasons why, but there are some non-obvious ones too.
        if (temp == 't')        Bo.push_back(0x00FF);
        else if (temp == 'f')    Bo.push_back(0x0000);

    // The name index is usually used to loop over the elements of an array, we would
    // usually call a variable representing the number of elements 'length' or 'size',
    // and we would not reduce it by 1.
    index = Bo.size() - 1;

    // So this line would be for (int i = 0; i < length; i++) - notice we use < instead of <=
    // rather than subtracting 1 from the number of elements.
    for (int i = 0; i <= index; i++)

        // I think you need to revise what '=' and '==' do.
        if (temp1 = 't') Bo[i] == 0x00FF;
        else if (temp1 = 'f') Bo[i] == 0x0000;

    // Why a new variable j, this makes it look like an inner loop - what's wrong with i?
    for (int j = 0; j <= index; j++)

        // Omitting { } around this line is a fast route to a maintenance and debugging nightmare.
        cout << Bo[j] << " ";

    // This time you _have_ resused i!
    i = 0;

        // Why are you changing the values of the array?
        Bo[i + 1] = andF;
 
  • Like
Likes Mark44 and Jarvis323
  • #21
4,943
110
C:
std::vector<uchar> vb;
while( 1 )
{
    char input = getUserInput();
    if(      input == 't' ) vb.push_back( true );
    else if( input == 'f' ) vb.push_back( false );
    else break;
}
I don't recall I've seen uchar in the book. It can take true or false? You can perform Boolean operation on each element?

Also, what is while( 1 )?

C++:
if( vb.size() )
{
    for( size_t i = 1, end = vb.size(); i < end; ++i )
    {
        vb[ i ] = vb[ i ] && vb[ i - 1 ];
    }
    vb[ 0 ] = vb[ 1 ];
}
Also, be careful with code like index = v.size() - 1 You can print out v.size() -1 when v is empty to see what I mean.
I don't follow this part:
What is if( vb.size() ) ? Is it if vb.size() = 0, it's false, or else it's true?

Also: for( size_t i = 1, end = vb.size(); i < end; ++i ) , what is size_t? Is it something I have not learn? I only know for(i=0; i<vb.size(); i++) {} type expression.

I am only on chapter 8 of Gaddis' book.

thanks
 
  • #22
370
219
I don't recall I've seen uchar in the book. It can take true or false? You can perform Boolean operation on each element?
Also, what is while( 1 )?
uchar is an 8 bit unsigned int. Like I said, in C and C++, 0 is treated as false and not 0 is treated as true.

size_t is an unsigned integer that represents the maximum size that a container can have. This is the type of the value that .size() returns. You might have seen compiler warnings when you assigned .size() to an int. It warns you because size() may be larger than an int can hold without overflowing. If your container had more than 2,147,483,647 elements, then the int would wrap around, for example becoming negative. It's critical to understand the implications of the types you are using. You can play around and try to see what happens when you exceed their limitations, when you use multiple types in a single expression, etc.

https://en.cppreference.com/w/c/types/size_t
 
Last edited:
  • Like
Likes yungman
  • #23
4,943
110
uchar is an 8 bit unsigned int. Like I said, in C and C++ 0 is treated as false and not 0 is treated as true.
I see. thanks
 
  • #24
370
219
You also need to know (but not now) that if you did need to write faster code you need to stay away from std::vector (and for that matter std::string and the other STL classes) because these do a lot of work behind the scenes managing memory allocation for you. With an array you have to do this yourself.
That's not necessarily true. There is no performance overhead using a vector instead of a raw dynamic array. The only issue is reallocation, which vector will do if it runs out of space while you are pushing new elements. But if you made your own version of a vector, you would need to do the same anyways. Maybe for a custom use case, you can use a better reallocation strategy. That would be the only improvement I can imagine you might make. With vector you can initialize with a specific size, reserve a certain amount of space, etc. If using these features to avoid the vector reallocating memory is enough, then you will gain nothing from using your own vector implementation.

And other STL classes like map, unordered_map, and list are perfectly fine implementations of the corresponding data structures. You can implement your own hash map, but do you really need to, and why should you expect to get a performance benefit?
 
  • #25
4,943
110
Also, be careful with code like index = v.size() - 1 You can print out v.size() -1 when v is empty to see what I mean.
How about
index = v.size()

Then in the later lines I use (i < (index - 1)) instead of (i < index)
 

Related Threads on Question about the efficiency of using an array or individual variables

Replies
8
Views
7K
  • Last Post
Replies
3
Views
3K
  • Last Post
Replies
2
Views
3K
Replies
12
Views
14K
Replies
3
Views
3K
Replies
1
Views
1K
Replies
7
Views
3K
Replies
11
Views
998
Top