Question about the efficiency of using an array or individual variables

Click For Summary
SUMMARY

The discussion centers on the efficiency of using boolean arrays versus individual boolean variables in C++. The consensus is that accessing individual variables (B0 to B9) is faster due to direct memory addressing, while accessing array elements (A[0] to A[9]) requires address calculation, which introduces overhead. Additionally, the initialization of boolean arrays requires explicit initialization for each element, as a single initializer only sets the first element. The conversation also touches on the limitations of static arrays and the advantages of using dynamic arrays, such as std::vector, for user-defined sizes.

PREREQUISITES
  • Understanding of C++ boolean data types
  • Familiarity with array and vector data structures in C++
  • Knowledge of memory addressing and performance implications
  • Basic understanding of C++ initialization rules for arrays
NEXT STEPS
  • Explore C++ memory management techniques, including dynamic allocation with new and delete
  • Learn about the performance characteristics of std::vector compared to static arrays
  • Investigate C++ initialization techniques for arrays and the implications of default initialization
  • Study the impact of cache memory on data access patterns in programming
USEFUL FOR

Software developers, particularly those working with C++ and focusing on performance optimization, as well as students learning about data structures and memory management in programming.

  • #31
I just want to update everyone, It is correct I DO NOT need the boolean array, just one boolean variable is good enough. I am on the bubble sort now. I am stuck on some other things that the program got hung up. I want to spend some time before I cry for help. I need to learn to solve my own problem...at least give it a real try.

Thanks.
 
  • Like
Likes Tom.G
Technology news on Phys.org
  • #32
Always remember the print statement is your friend. It can always help you to find most of your bugs unless you introduce one in it too.
 
  • Like
Likes yungman
  • #33
jedishrfu said:
Always remember the print statement is your friend. It can always help you to find most of your bugs unless you introduce one in it too.
If I can give you a double like, I would! I did NOT know I can print the .cpp! I always had to copy onto word.

Yes, it's much easier to read on paper, so far I am stuck, hopefully reading from the paper can help. I still have not taken a peek at the the program in the book, I want to do it on my own first. But it's getting very short already. I must have put something in an infinite loop somewhere. But when I put in count<<"..." to print out where I am in the program at different spot, it gave me correct answer.

Thanks

BTW, I only follow the uchar discussion on and off, too busy. So should I put in my notes to use it if it only works in VS? But in reality, even if I use short int that is 2bytes, it's not a big deal as memory is cheap now a days. At least I don't need it now, but spending a day looking into this sure learn a lot.
 
  • #34
I got it. With the print out, it's easier, I spotted one error from the print, but the most important and stupid one is I put a ';' at the end of the function definition. It skip the function all together!
C++:
// 8.4 Alan bubble sort
#include <iostream>
#include <vector>
using namespace std;
void sortAr(vector <int>&, int&);//sorting function with reference parammeters of vector SA and size of the vector
void InputAr(vector <int>&, int&);// to get numbers from user.
int main()
{
    int sz;
    vector <int> SA;// vector to store the numbers from user for sorting
    InputAr(SA, sz);// For user to input numbers for sorting
    count << " The size of vector SA is " << SA.size();
    count << "     SA = {";
    for (int i = 0; i < sz; i++)
        count << SA[i] << " ";
    count << "} \n\n";

    sortAr(SA, sz);
    count << " The result after sorting = {";
    for (int i = 0; i < sz; i++)
        count << SA[i] << " ";
    count << "} \n\n";
    return 0;
}
void InputAr(vector<int>&Av, int &size)// to get numbers from user.
{
    int num;
    do
    {
        count << " Enter any +ve integer to be sorted, enter -1 to quit "; cin >> num;
        if (num >= 0)
            Av.push_back(num);// Put new number into the last element starting with Av[0].
    } while (num >= 0);// only take numbers >=0, -ve number to terminate.
    count << "\n\n";
    size = Av.size();
}

void sortAr(vector <int>& AR, int &size)
{       
    bool nSwap;
    int h = 1, temp;
    do
    {
       
        nSwap = true;// start the do-while with nSwap = true, let the inner while loop to change to false.
        h = 1; //Reset h = 1 and start over again.
        while (h < size)
        {
            if (AR[h-1] > AR[h])
            {
                nSwap = false;// If there is a swap, it is change to false
                temp = AR[h-1];
                AR[h-1] = AR[h];
                AR[h] = temp;//swap AR[h-1] with AR[h]
            }
            h = h + 1;
        }
    } while (nSwap == false);// repeat as long as one pair of elements need to be swap.
}

The ';' I put was at the end of line 38! That screwed up everything.

I looked at the program in the book, the sorting is very similar, but I made it fancier by letting user to input any number and any amount of numbers to sort. The book only use a fixed 6 elements array to sort. That's too easy. I am stoked.BUT, I still have an issue. I am supposed to put -1 to signal I want to quit after entering the numbers. BUT if I hit other key like 'q', it will run non stop and I can see the cmd screen keep rolling and rolling until I close the cmd window. Why?

Thanks
 
  • #35
I got burned by the semicolon a few times when writing code in a hurry:
C:
while(x<3);
{
  ...do something...
}

vs

C:
while(x<3) { ;
   ...do something...
}

The semicolon error of the first one didn't execute the { } block repeatedly while x<3 so I changed my programming style to use the { on the same line where now any errant semicolon is inside the block and so becomes a null statement.

I think modern IDE tools may have options to spot the "mistake" and flag it.
 
  • Like
Likes yungman
  • #36
yungman said:
BUT, I still have an issue. I am supposed to put -1 to signal I want to quit after entering the numbers. BUT if I hit other key like 'q', it will run non stop and I can see the cmd screen keep rolling and rolling until I close the cmd window. Why?
If the << operator can't parse the input as a number, it won't consume the input.
You need to test cin.fail() to see if reading a number worked, and if it didn't work, either stop reading more numbers, or use cin.ignore() to consume the wrong input until you can succesfully read a number again.
 
  • Like
Likes yungman
  • #37
yungman said:
BTW, I only follow the uchar discussion on and off, too busy. So should I put in my notes to use it if it only works in VS?
Instead, you can always use 'unsigned char' which is in standard C++. 'uchar' is simply a shortened name that Microsoft defines in Visual Studio for convenience.
 
  • #38
Regarding the original question, here is what Microsoft Visual C++ does with it using the default optimization settings:

Code:
  bool A[10] = {1, 1, 0, 1, 1, 1, 1, 1, 1, 1};
00141056  mov         dword ptr [ebp-10h],1010101h
0014105D  mov         dword ptr [ebp-0Ch],1010101h
00141064  mov         word ptr [ebp-8],101h

  bool B0 = true, B1 = true, B2 = true, B3 = true, B4 = true, B5 = true, B6 = true, B7 = true, B8 = true, B9 = true;
<optimized out>

  // I declared these volatile to prevent their assignments from being optimized out.
  volatile 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];
0014106A  mov         byte ptr [ebp-1],1

  Bn = B0 && B1 && B2 && B3 && B4 && B5 && B6 && B7 && B8 && B9;
0014106E  mov         byte ptr [ebp-2],1

Also, I moved this into a separate function to make it easier to identify the assembler code. That didn't work. It moved it back inline.

Those 8-hexadigit numbers to the left of the assembler are the actual memory addresses used during program execution.

As you can see, both the An assignment and the Bn assignment were reduced to "Xn=1;".
The only difference was that the default optimization did not get rid of the array - in insisted on creating the array even though it was never used.

The bottom line: Using the array took 9.5 times as much memory [38 bytes (28 code bytes + 10 data bytes) vs. 4 code bytes] and roughly 4 or 5 times as much execution time. Execution time is harder to determine because it is dependent on the processor's particular caching features and the cache states when the code is executed.

This is is good at showing the difference between a MSVC "debug" build (no optimizations) and a "release" build (default optimizations). Using the release build, setting breakpoints becomes problematic. Since it moved my function inline, it was not possible to put a breakpoint anywhere in that source code. Instead, I needed to put the breakpoint on the call to that function.
 
Last edited:
  • #39
I am on fire! I did the Selection sort in one evening!
C++:
// 8.5 Selection sort
#include <iostream>
#include <vector>
using namespace std;
void sortAr(vector <int>&, int&);
void InputAr(vector <int>&, int&);
int main()
{
    int sz;
    vector <int> SA;
    InputAr(SA, sz);
    count << " The size of vector SA = " << SA.size()<< "\n\n";
    count << " SA = {";
    for (int i = 0; i < sz; i++)
        count << SA[i] << " ";
    count << "} \n\n";
    sortAr(SA, sz);
    count << " The numbers after sorting of vector SA = ";
    count << " {";
    for (int i = 0; i < sz; i++)
        count << SA[i] << " ";
    count << "} \n\n";
    return 0;
}
void InputAr(vector<int>&Av, int &size)
{
    int num;
    do
    {
        count << " Enter any +ve integer to be sorted, enter -1 to quit "; cin >> num;
        if (num >= 0)
            Av.push_back(num);
    } while (num >= 0);
    count << "\n\n";
    size = Av.size();
}
void sortAr(vector <int>& AR, int& size)
{
    int startScan = 0, index, temp;
    do
    {
        index = startScan + 1;;
        while (index < size)
        {
            if (AR[startScan] > AR[index])//comparing the lowest number element starting with AR[0] to the rest 
            {                    // one by oneswitch with them if it is higher than the other elements.
                temp = AR[startScan];
                AR[startScan] = AR[index];
                AR[index] = temp;
            }
            index = index + 1;// to the next higher element to compare,  AR[1]->AR[2]-> AR[3]...
        }
        startScan = startScan + 1;
    } while (startScan < (size - 1));
}
I am stoked, no question on this. Now I am going to work on why if I put a char instead of -1 to quit and causes the program into an infinite loop.
 
  • Like
Likes jedishrfu
  • #40
I cannot figure out why when I hit character instead of -1, it will not quit and run in loop. I simplified to just a few lines. Please help:
C++:
// infinite loop when enter character
#include <iostream>
#include <vector>
using namespace std;
void InputAr();
int main()
{
    int sz;
    InputAr();
    return 0;
}
void InputAr()
{
    int num;
    do
    {
        count << " Enter any +ve integer to be sorted, enter -1 to quit "; cin >> num;
    } while (num >= 0);
}
Problem seems to be in line 18.
Thanks
 
  • #41
See post #36. If the input isn't a valid number, num won't change, and the non-numeric characters won't be removed from the input stream.
 
  • Like
Likes yungman
  • #42
Here's a example of how one might deal with this sort of input error. It takes advantage of the fact that when you use an input expression like cin << num in a Boolean expression, it evaluates as true or false depending on whether the input succeeded.

In addition to cin.ignore(), you also need to use cin.clear().

C:
#include <iostream>

using namespace std; // for conciseness because this is only a toy program

int main ()
{
    int num;
    cout << "Please enter an int: ";
    while (!(cin >> num))
    {
        cin.clear();  // reset the stream's failure flag
        // discard 100 chars, or until the next '\n', whichever comes first
        cin.ignore (100, '\n');
        cout << "That's not an int. Please try again: ";
    }
    cout << "OK, you entered " << num << endl;
    return 0;
}
Code:
% g++ inputerror.cpp -o inputerror
% ./inputerror
Please enter an int: 23
OK, you entered 23
% ./inputerror
Please enter an int: fooey
That's not an int. Please try again: 42
OK, you entered 42
% ./inputerror
Please enter an int: eeny
That's not an int. Please try again: meeny
That's not an int. Please try again: 42
OK, you entered 42
Alternative version using cin.fail(). Note cin >> num appears twice.
C:
#include <iostream>

using namespace std; // for conciseness because this is only a toy program

int main ()
{
    int num;
    cout << "Please enter an int: ";
    cin >> num;
    while (cin.fail())
    {
        cin.clear();  // reset the stream's failure flag
        // discard 100 chars, or until the next '\n', whichever comes first
        cin.ignore (100, '\n');
        cout << "That's not an int. Please try again: ";
        cin >> num;
    }
    cout << "OK, you entered " << num << endl;
    return 0;
}
 
Last edited:
  • Like
Likes yungman
  • #43
jtbell said:
Here's a example of how one might deal with this sort of input error. It takes advantage of the fact that when you use an input expression like cin << num in a Boolean expression, it evaluates as true or false depending on whether the input succeeded.

In addition to cin.ignore(), you also need to use cin.clear().

C:
#include <iostream>

using namespace std; // for conciseness because this is only a toy program

int main ()
{
    int num;
    cout << "Please enter an int: ";
    while (!(cin >> num))
    {
        cin.clear();  // reset the stream's failure flag
        // discard 100 chars, or until the next '\n', whichever comes first
        cin.ignore (100, '\n');
        cout << "That's not an int. Please try again: ";
    }
    cout << "OK, you entered " << num << endl;
    return 0;
}
Code:
% g++ inputerror.cpp -o inputerror
% ./inputerror
Please enter an int: 23
OK, you entered 23
% ./inputerror
Please enter an int: fooey
That's not an int. Please try again: 42
OK, you entered 42
% ./inputerror
Please enter an int: eeny
That's not an int. Please try again: meeny
That's not an int. Please try again: 42
OK, you entered 42
Alternative version using cin.fail(). Note cin >> num appears twice.
C:
#include <iostream>

using namespace std; // for conciseness because this is only a toy program

int main ()
{
    int num;
    cout << "Please enter an int: ";
    cin >> num;
    while (cin.fail())
    {
        cin.clear();  // reset the stream's failure flag
        // discard 100 chars, or until the next '\n', whichever comes first
        cin.ignore (100, '\n');
        cout << "That's not an int. Please try again: ";
        cin >> num;
    }
    cout << "OK, you entered " << num << endl;
    return 0;
}
Thanks so much, that works.

I have 3 books on C++, I can't find either
while (!(cin >> num)) OR if (!(cin >> num))
I did not know (cin >> num) can be a boolean to tell whether the input is NOT a number.

Thank you so much. Looks like I am going to finish chapter 8 sooner than I expected...knock on wood.
 
  • #44
I must be asking for it, I want to make the exercise more challenging, I am stuck on trying to do either a vector of strings or a 2D vector of char. This is the array I want to make into vector:
C++:
const int Row = 9, ProdCol = 31;
char Prod[Row][ProdCol] = { {"Six Steps to Leadership"}, {"Six Steps to Leadership"}, {"Road to Exellence"},
                {"Seven Lessons of Quality"},{"Seven Lessons of Quality"},{"Seven Lessons of Quality"},
                {"Teams Are Made, Not Born"}, {"Leadership for the Future"}, {"Leadership for the Future"} };

I went on line to try to look up 2D vector. It's easy to create 2D vector of numbers:

C++:
    vector<vector<int> > vect{ { 1, 2, 3 },
                               { 4, 5, 6 },
                               { 7, 8, 9 } };

BUT, it doesn't work for characters like this:

C++:
        vector<vector<char> > vect{ { "this is a test" },
                                    { "Second test"},
                                    { "Third test"} };

I looked up using vector of strings, it's over my head, I don't understand this:

C++:
    std::string s = "Hello World!";

    std::vector<char> v(s.begin(), s.end());

    for (const char& c : v)
        std::count << c;

Is there any way to use vector that is within my knowledge level? If it is too advance for me, let me know.

Thanks
 
Last edited:
  • #45
If your compiler supports the C++ 2011 standard, you should be able to compile this.

C:
#include <iostream>
#include <string>
#include <vector>

using namespace std; // for brevity since this is just a toy program

int main ()
{
    vector<string> titles = { "Six Steps to Leadership",
                              "Six Steps to Leadership",
                              "Seven Lessons of Quality",
                              "Seven Lessons of Quality",
                              "Seven Lessons of Quality",
                              "Teams Are Made, Not Born",
                              "Leadership for the Future" };

    for (int k = 0; k < titles.size(); ++k)
    {
        cout << titles[k] << endl;
    }

    return 0;
}
With my compiler, I have to specify c++11 explicitly, otherwise it uses an earlier standard.
Code:
% g++ -std=c++11 vecstrings.cpp -o vecstrings
% ./vecstrings
Six Steps to Leadership
Six Steps to Leadership
Seven Lessons of Quality
Seven Lessons of Quality
Seven Lessons of Quality
Teams Are Made, Not Born
Leadership for the Future
%
You're using Visual Studio, right? Then see this Microsoft support page if necessary:

/std (Specify Langauge Standard Version)

According to that page, VS 2017 or later defaults to C++ 2014 (which of course includes all the features of C++ 2011), so you should be OK unless you're using an older version of VS.
 
Last edited:
  • Like
Likes yungman
  • #46
yungman said:
I have 3 books on C++, I can't find either
while (!(cin >> num)) OR if (!(cin >> num))
I did not know (cin >> num) can be a boolean to tell whether the input is NOT a number.
I don't remember whether I learned that technique in the textbook I was teaching from, or some other book, or online. It was 15-20 years ago.

A similar technique is commonly used when reading files, for detecting the end of file. (One way the input can fail is to reach the end of file.) Your book might discuss examples like this:

C:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>

using namespace std; // for brevity since this is just a toy program

int main ()
{
    ifstream inputFile ("titles.txt");
    if (inputFile.fail())
    {
        cout << "Sorry, can't open titles.txt!" << endl;
        return 0;
    }

    vector<string> titles;
    string eachTitle;
    while (getline (inputFile, eachTitle))
    {
        titles.push_back (eachTitle);
    } 
    
    inputFile.close();

    for (int k = 0; k < titles.size(); ++k)
    {
        cout << titles[k] << endl;
    }

    return 0;
}
The file titles.txt:
Code:
Six Steps to Leadership
Six Steps to Leadership
Seven Lessons of Quality
Seven Lessons of Quality
Seven Lessons of Quality
Teams Are Made, Not Born
Leadership for the Future
And the output:
Code:
% g++ vecstringsfile.cpp -o vecstringsfile
% ./vecstringsfile
Six Steps to Leadership
Six Steps to Leadership
Seven Lessons of Quality
Seven Lessons of Quality
Seven Lessons of Quality
Teams Are Made, Not Born
Leadership for the Future
I'm pretty sure I remember teaching this method. It also works with the >> operator. Your book might prefer to use the eof() member function instead:
C:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>

using namespace std; // for brevity since this is just a toy program

int main ()
{
    ifstream inputFile ("titles.txt");
    if (inputFile.fail())
    {
        cout << "Sorry, can't open titles.txt!" << endl;
        return 0;
    }

    vector<string> titles;
    string eachTitle;
    while (true)
    {
        getline (inputFile, eachTitle);
        if (inputFile.eof()) break;  // without this we would have an infinite loop
        titles.push_back (eachTitle);
    } 
    
    inputFile.close();

    for (int k = 0; k < titles.size(); ++k)
    {
        cout << titles[k] << endl;
    }

    return 0;
}
 
  • Like
Likes yungman
  • #47
jtbell said:
I don't remember whether I learned that technique in the textbook I was teaching from, or some other book, or online. It was 15-20 years ago.

A similar technique is commonly used when reading files, for detecting the end of file. (One way the input can fail is to reach the end of file.) Your book might discuss examples like this:

C:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>

using namespace std; // for brevity since this is just a toy program

int main ()
{
    ifstream inputFile ("titles.txt");
    if (inputFile.fail())
    {
        cout << "Sorry, can't open titles.txt!" << endl;
        return 0;
    }

    vector<string> titles;
    string eachTitle;
    while (getline (inputFile, eachTitle))
    {
        titles.push_back (eachTitle);
    }
   
    inputFile.close();

    for (int k = 0; k < titles.size(); ++k)
    {
        cout << titles[k] << endl;
    }

    return 0;
}
The file titles.txt:
Code:
Six Steps to Leadership
Six Steps to Leadership
Seven Lessons of Quality
Seven Lessons of Quality
Seven Lessons of Quality
Teams Are Made, Not Born
Leadership for the Future
And the output:
Code:
% g++ vecstringsfile.cpp -o vecstringsfile
% ./vecstringsfile
Six Steps to Leadership
Six Steps to Leadership
Seven Lessons of Quality
Seven Lessons of Quality
Seven Lessons of Quality
Teams Are Made, Not Born
Leadership for the Future
I'm pretty sure I remember teaching this method. It also works with the >> operator. Your book might prefer to use the eof() member function instead:
C:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>

using namespace std; // for brevity since this is just a toy program

int main ()
{
    ifstream inputFile ("titles.txt");
    if (inputFile.fail())
    {
        cout << "Sorry, can't open titles.txt!" << endl;
        return 0;
    }

    vector<string> titles;
    string eachTitle;
    while (true)
    {
        getline (inputFile, eachTitle);
        if (inputFile.eof()) break;  // without this we would have an infinite loop
        titles.push_back (eachTitle);
    }
   
    inputFile.close();

    for (int k = 0; k < titles.size(); ++k)
    {
        cout << titles[k] << endl;
    }

    return 0;
}
Thanks for all the help, Your first example works like a champ. I already put it in my notes and moved on.
 
  • #48
I am stuck on a new problem. This is on passing vector to function.
C++:
//
//
//
#include <iostream>
#include <iomanip>
#include <vector>
using namespace std;
void getnumSold(vector<int>&);
vector<int>DefaultNSold = { 842, 416, 127, 514, 437, 269, 97, 492, 212 };
int main()
{
    vector<int>Sold(9);
    getnumSold(Sold);// copy vector DefaultNSold into Sold
    count << "In main return from getnumSold Sold = {";
    for (int i = 0; i < 9; i++)
        count << Sold[i] << " ";
    count << "} \n\n";// To show it got copied over
    return 0;
}
void getnumSold(vector<int>& numSold)// reference to return the values to Sold in main
{
        int row;
        vector<int>numSold(DefaultNSold);//copy the content of DefaultNSold into numSold
        count << " In getnumSold, You chose to use default = {";
        for (row = 1; row < DefaultNSold.size(); row++)
        {
            count << numSold[row - 1] << " ";
        }
}
I don't know why I get an error. I checked through the syntax and I cannot find any problem.

It is a very simple program, just calling a function that copy the vector DefaultNSold into numSold and display numSold to show it copy back to vector SOLD in main().

Please help.

Thanks
Compile error Listing 7.2.jpg
 
  • #49
You need to get better at reading error messages. The message says "redefininition of formal parameter 'numSold' on line 23" which clearly tells you all you need to know: on line 23 you redefine numsold which was already defined as a parameter to the function.

Also the code for iterating rows has a number of problems:

C:
       for (row = 1; row < DefaultNSold.size(); row++)
        {
            count << numSold[row - 1] << " ";
        }

This will miss the last row (think about what happens if size() returns 1). C++ indices start at zero, starting at 1 and then subtracting 1 makes no sense at all - remember what a mess you got into before doing this? It is also not a good idea to use a different array (DefaultNSold) for the limit than the one you are iterating over (numSold) - this makes it difficult to debug (and also makes it almost impossible for the compiler to optimize).

The standard way to write this sort of loop is like this:

C:
    for (int row = 0; row < numSold.size(); row++) {
        count << numSold[row] << " ";
    }

Oh and for the umpteenth time stop mixing capital letters at the beginning of variable names - (DefaultNSold and numSold). A good convention is to use camelCase for variable names, this means you can save PascalCase for names of classes and structs.
 
  • #50
jedishrfu said:
I think modern IDE tools may have options to spot the "mistake" and flag it.
I know for sure that Visual Studio will flag it, the community edition is free and pretty easy to use. I go back and forth between command line and IDE.
 
  • Like
Likes jedishrfu
  • #51
I just started playing with VS recently after a forced move away from Macs to Windows-based machines.

Its not bad and looks to be a powerful competitor to Sublime and Jetbrains IDEs.

The only saving grace was the Ubuntu WSL option. VS can run in both windows and remotely in Ubuntu ie a server runs on Ubuntu to connect to VS for code editing. I haven't gotten it working yet due to air gap reasons but hope to soon.

I did find that you can download extensions for offline installation. MS makes it really easy with a link on the righthand side of the extension summary page and an option in the editor to import extensions from files. Works well unless the extension depends on other extensions and then you have to dig somewhat to figure that out.
 
  • #52
pbuk said:
You need to get better at reading error messages. The message says "redefininition of formal parameter 'numSold' on line 23" which clearly tells you all you need to know: on line 23 you redefine numsold which was already defined as a parameter to the function.

Also the code for iterating rows has a number of problems:

C:
       for (row = 1; row < DefaultNSold.size(); row++)
        {
            count << numSold[row - 1] << " ";
        }

This will miss the last row (think about what happens if size() returns 1). C++ indices start at zero, starting at 1 and then subtracting 1 makes no sense at all - remember what a mess you got into before doing this? It is also not a good idea to use a different array (DefaultNSold) for the limit than the one you are iterating over (numSold) - this makes it difficult to debug (and also makes it almost impossible for the compiler to optimize).

The standard way to write this sort of loop is like this:

C:
    for (int row = 0; row < numSold.size(); row++) {
        count << numSold[row] << " ";
    }

Oh and for the umpteenth time stop mixing capital letters at the beginning of variable names - (DefaultNSold and numSold). A good convention is to use camelCase for variable names, this means you can save PascalCase for names of classes and structs.

Thanks for the reply, but it's not that simple. I spent hours on this, going through my notes and search on line to verify my syntax was correct, I experimented a lot on each individual pieces before I posted. This is the almost exact program and doesn't give me an error, by just adding "{" and "}" in line 25 and 34. as shown below. But if you run the program below, the content of numSold in the function will not pass back to Sold in the main. That's where I started the trouble shooting.
I experimented individual pieces on passing the function, they all worked, just together it doesn't.

On line 23 where the error is, this is the syntax vector<int>numSold(DefaultNSold); for copying content of vector to another vector. I know it repeat the definition, BUT it will not work if I just put numSold(DefaultNSold); I've gone through all that.

C++:
#include <iostream>
#include <iomanip>
#include <vector>
using namespace std;

void getnumSold(vector<int>&);
vector<int>DefaultNSold = { 842, 416, 127, 514, 437, 269, 97, 492, 212 };

int main()
{
    char key = 'A';
    vector<int>Sold(DefaultNSold.size());//receive number sold for each item.
    getnumSold(Sold);//passing vector Sold to function getnumSold().
    count << "In main return from getnumSold Sold = {";
    for (int i = 0; i < 9; i++)
        count << Sold[i] << " ";
    count << "} \n\n";
    return 0;
}void getnumSold(vector<int>& numSold)
{

    {
        int row;
        vector<int>numSold(DefaultNSold);
        count << " In getnumSold, You chose to use default = {";
        for (row = 1; row < DefaultNSold.size(); row++)
        {
            count << numSold[row - 1] << " ";
        }
        count << numSold[row - 1] << "}\n\n";
    }
}

About the row =1 to row < size-1, It was NOT the complete program as I tried to cut all the irrelevant lines to make the program as short to read as possible. You can see the more complete program I put in this time. The reason is I need to put "}" AFTER the last number(shown in line 33), I cannot put this in the loop. So I use one extra line to put in the last number. Note that row++ after exit from the for loop. Line 33 points to the last element.

I spent a lot of hours on this before I posted, I know better to check everything first. This is really funky.

Thanks
 
Last edited:
  • #53
This is the original program before I started cutting lines to simplify for posting here. It compiles but parameters won't pass that started the whole thing. It's too long for anyone to read through all the irrelevant lines. It's not complete, I even blocked out some part that doesn't pertain to the problem.

From working on this, I have the suspicion that copying vector using vector<int>numSold(DefaultNSold) with passing parameter with & to the function together that gives the problem. I experimented individually, they all worked, just together that's when problem starts.

I know I can put the vectors in global where everyone can access will work. But I want to practice passing parameters with reference. This is to me very important for future.

I know using array will work a lot easier and I did that already, but that's not the point. I want to practice on passing reference vectors.

C++:
#include <iostream>
#include <iomanip>
#include <vector>
using namespace std;

void getnumSold(vector<int>&);
void getProdNum(int &);
void Bsearch(int[], int size, int num, int &);
//void displayProd(vector<int>&);

const int Row = 9, ProdCol = 31;
char Prod[Row][ProdCol] = { {"Six Steps to Leadership"}, {"Six Steps to Leadership"}, {"Road to Exellence"},
                {"Seven Lessons of Quality"},{"Seven Lessons of Quality"},{"Seven Lessons of Quality"},
                {"Teams Are Made, Not Born"}, {"Leadership for the Future"}, {"Leadership for the Future"} };

char Desc[Row][ProdCol] = { {"Book"}, {"Audio CD"}, {"DVD"},
                {"Book"}, {"Audio CD"}, {"DVD"},
                {"Book"}, {"Book"}, {"Audio CD"} };

float Price[] = { 12.95, 14.95, 18.95, 16.95,
                21.95, 31.95, 14.95, 14.95, 16.95 };

int pnAr[] = { 914, 915, 916, 915, 918,//   0, 1, 2, 3, 4
              919, 920, 921, 922 };//        5, 6, 7, 8

vector<int>DefaultNSold = { 842, 416, 127, 514, 437, 269, 97, 492, 212 };

int main()
{
    char key = 'A';
    vector<int>Sold(DefaultNSold.size());//receive number sold for each item.
    int partNum;// part number of the book from customer.
    getnumSold(Sold);//passing vector Sold to function getnumSold().
    count << "In main return from getnumSold Sold = {";
    for (int i = 0; i < 9; i++)
        count << Sold[i] << " ";
    count << "} \n\n";
    //displayProd(Sold);//Show all the tittles of the items
    return 0;
}

/*void displayProd(vector<int>&Sold)// display the table of selections and price.
{
    count << left << setw(35) << "     Product" << setw(15) << "Decription" << setw(10) << "Part num" <<
    setw(15) << "   Price" << setw(10) << "sold" << "\n\n";
    for (int line = 0; line < Row; line++)
    {
        count << "  " << left << setw(35) << Prod[line] << left << setw(15) <<
        Desc[line] << setw(10) << pnAr[line] << "$" << Price[line] <<
        right << setw(10) << Sold[line] << "\n\n";
    }
}*/

void getnumSold(vector<int>& numSold)
{
    char select;
    count << " Enter y to use default numbers, any other character";
    count << "for entering 6 new numbers: "; cin >> select;
    if ((select == 'y') || (select == 'Y'))
    {
        int row=1;
        vector<int>numSold(DefaultNSold);  
        count << " In getnumSold, You chose to use default = {";
        for (row = 1; row < DefaultNSold.size(); row++)
        {
            count << numSold[row - 1] << " ";
        }
        count << numSold[row - 1] << "}\n\n";
    }
    else
    {
        count << " You chose to enter 9 new sales number.\n\n";
        count << "Enter number sold for the following\n\n";
        for (int row = 1; row <= DefaultNSold.size(); row++)
        {
            count << "   " << left << setw(35) << Prod[Row-1] << left <<
                setw(15) << Desc[row-1] << "$" << Price[row-1] << " is:   ";
            cin >> numSold[row-1];
        }
    }
}
 
Last edited:
  • #54
I think there's something wrong with this vector<int>numSold(DefaultNSold). I wasted a day on this, now I just do it the dumb way and works like a champ:
C++:
#include <iostream>
#include <iomanip>
#include <vector>
using namespace std;

void getnumSold(vector<int>&);
vector<int>DefaultNSold = { 842, 416, 127, 514, 437, 269, 97, 492, 212 };

int main()
{
    char key = 'A';
    vector<int>Sold(DefaultNSold.size());//receive number sold for each item.
    getnumSold(Sold);//passing vector Sold to function getnumSold().
    count << "In main return from getnumSold Sold = {";
    for (int i = 0; i < 9; i++)
        count << Sold[i] << " ";
    count << "} \n\n";
    return 0;
}void getnumSold(vector<int>& numSold)
{
int row = 1;
count << " In getnumSold, You chose to use default = {";
for (row = 1; row < DefaultNSold.size(); row++)
{
    numSold[row - 1] = DefaultNSold[row - 1];
    count << numSold[row - 1] << " ";
}
numSold[row - 1] = DefaultNSold[row - 1];
count << numSold[row - 1] << "}\n\n";

}

I just use for loop to copy DefaultNSold to numSold. No problem passing back the parameter from function to main. Everything works. What a waste of time trying a new "more convenient" instruction. I don't think in real time operation, the vector<int>numSold(DefaultNSold) is any more efficient than a for loop.

I've been on line searching, I cannot find anything on vector<int>numSold(DefaultNSold). I saw plenty examples using for loop to copy.

There's something to be said NOT to try to be fancy just to save a line, do it the primitive and dumb way might end up getting ahead. I might have finish chapter 8 if I were not trying to be fancy. This is my philosophy in my whole career and served me well. Do it simple, do it reliable and do it fast. Don't try to save a penny and lose a pound.
 
Last edited:
  • #55
Efficiency is seldom on the mind of a programmer with a deadline and some requirements. Often we will write code so that it is easily maintainable.

Other times we will code in constants thinking that'll never change and since we're in a hurry let's move on to darn I wish I coded it as a named constant as you scan through your code trying to decide the linkages of one constant value to another.

Fancy operators and cute tricks are replaced by more reliable easily read code. In C and C++ there was a contest on code obsfucation ie how to make the most compact and unreadable c code which involved one letter variable names, removal of spaces and newlines, and operator tricks to further confuse.

The ++ pre and post operators can make some interesting reading as compilers differ as to how they are interpreted. As an example, (++x - x++) = ? where x is some integer.

Some odd examples are found within these "rules" for C and C++:

https://rules.sonarsource.com/cpp
 
  • #56
yungman said:
Thanks for the reply, but it's not that simple.
I know that when you can't see the problem it doesn't look simple, but it really is.

yungman said:
I spent hours on this, going through my notes and search on line to verify my syntax was correct,
If your syntax was wrong then it would have said 'Syntax error', not told you about trying to define a variable twice.

yungman said:
I experimented a lot on each individual pieces before I posted. This is the almost exact program and doesn't give me an error, by just adding "{" and "}" in line 25 and 34. as shown below. But if you run the program below, the content of numSold in the function will not pass back to Sold in the main. That's where I started the trouble shooting.
It doesn't give you an error because by adding { and } you have created an inner scope where you can declare variables that are only visible within that scope. So it allows you to redefine numSold and work with it, but as soon as it reaches the end of that inner scope the new numSold is forgotton.

I suggest you stop working on this and move on and learn some more C++. You need to get on to the chapters on structs, classes and pointers because at the moment you are like the man trying to hit a screw in with a hammer because he hasn't learned about screwdrivers yet.

yungman said:
About the row =1 to row < size-1, It was NOT the complete program as I tried to cut all the irrelevant lines to make the program as short to read as possible. You can see the more complete program I put in this time. The reason is I need to put "}" AFTER the last number(shown in line 33), I cannot put this in the loop. So I use one extra line to put in the last number. Note that row++ after exit from the for loop. Line 33 points to the last element.
In that case you simply need to do:
C++:
   for (int row = 0; row < numSold.size() - 1; row++) {
        count << numSold[row] << " ";
    }
    count << numSold[row] << "}\n\n";
 
  • #57
jedishrfu said:
The ++ pre and post operators can make some interesting reading as compilers differ as to how they are interpreted.
That is not true, all compilers stick to the standard.
jedishrfu said:
As an example, (++x - x++) = ? where x is some integer.
That is not a difference in implementation of ++x or x++, that is a difference in whether the compiler process the left half or right half of the expression first - and the C++ standard states that this is not defined i.e. the compiler can decide which to do first - and can even leave the order decision to run time and do it differently each time.
 
  • #58
  • #59
pbuk said:
I know that when you can't see the problem it doesn't look simple, but it really is.If your syntax was wrong then it would have said 'Syntax error', not told you about trying to define a variable twice.
Because my syntax was not wrong.
pbuk said:
It doesn't give you an error because by adding { and } you have created an inner scope where you can declare variables that are only visible within that scope. So it allows you to redefine numSold and work with it, but as soon as it reaches the end of that inner scope the new numSold is forgotton.
I figured that much already.

pbuk said:
I suggest you stop working on this and move on and learn some more C++. You need to get on to the chapters on structs, classes and pointers because at the moment you are like the man trying to hit a screw in with a hammer because he hasn't learned about screwdrivers yet.
So there is no fix on this other than quit using vector<int>set1(set2) with function passing vector as reference? This is NOT about hitting screw with hammer, it's a matter either I did something wrong that I don't know, or something is wrong with the that line. I know one can NOT pass parameter without declaring
void getnumSold( vector<int>&numSold). Also one has to write vector<int>numSold(DefaultNSold) in order to copy from DefaultNSold into numSold . So this is catch 22. I know this is a problem. How do people solve this?

pbuk said:
In that case you simply need to do:
C++:
   for (int row = 0; row < numSold.size() - 1; row++) {
        count << numSold[row] << " ";
    }
    count << numSold[row] << "}\n\n";
I want row to represent the real row number. The way I do works.
 
  • #60
jedishrfu said:
Efficiency is seldom on the mind of a programmer with a deadline and some requirements. Often we will write code so that it is easily maintainable.
That's exactly what is so wrong with all the new products that use embedded software/firmware, computers, printers and all that. As the processor speed gets faster, memory gets bigger, things are getting slower and slower( I mean literally), things gets more and more unreliable. This is my experience with laptops, printers, smart tv, cars. Literally anything that involves computer. I have all name brand stuffs, the most sickening things is I had the same brand older models and they ALL WORKED. BUT when I bought the newer models, they suck to holy hell. the car, the printer, the tv, you name it.
I had a 2003 Mercedes E class, it was so reliable and so good. Lasted 15 years and was still good when we got rid of it. I bought a 2014 Mercedes ML, never been to the shop yet. We love them so much and bought a 2018 E class. It was in the shop over 5 weeks in the first 8 months all because of computer problems. The response with everything is so so slow. When the computer is doing something, everything else stops! You try to do simple things like shifting the transmission from D to R, it will take 3 sec to do. Try to make a 3 point turn on a busy street! Problems never got fixed, we just gave up.

then the printers, even my Samsung LED tv. My 65" works perfectly, my new 82" is something else. Color is wrong, had an intermittent issue I am still trying to track. I went through 5 or 6 printers in the last 3 years. They are all so intermittent.

jedishrfu said:
Other times we will code in constants thinking that'll never change and since we're in a hurry let's move on to darn I wish I coded it as a named constant as you scan through your code trying to decide the linkages of one constant value to another.

Fancy operators and cute tricks are replaced by more reliable easily read code. In C and C++ there was a contest on code obsfucation ie how to make the most compact and unreadable c code which involved one letter variable names, removal of spaces and newlines, and operator tricks to further confuse.

The ++ pre and post operators can make some interesting reading as compilers differ as to how they are interpreted. As an example, (++x - x++) = ? where x is some integer.

Some odd examples are found within these "rules" for C and C++:

https://rules.sonarsource.com/cpp
I said this before, I might be new in programming, I have been the chief EE and manager of EE for decades in real world in environment of the company sink or swim depending on the success of the product I designed. I hold dearly the philosophy of make it simple, make it reliable and do it fast. In hardware, a line of code is like a component that actually cost money. I still push my group to design is the most straight forward way, the most reliable way. Don't get fancy, that the success is measure on how reliable the product, deliver on time. NOT how "wise" is the circuit design.

the new stuffs are NOT convenient, it's a headache to use. Just no choice, things are not made to last, you have to buy new ones. I just gave away my 72" Mitsubishi rear projection tv that lasted 15 years. The color is a MILE better than the fancy Samsung LED tvs( I mean all of them). I had to gave it away because it's too big. I am very into top end hifi, the big Mitsubishi is blocking the sound and make the living room looks busy. I had to give it away and replace it with a 82" LED tv. That was a downgrade. BUT, the sound of my hifi got a lot better.
 

Similar threads

  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 7 ·
Replies
7
Views
2K
  • · Replies 6 ·
Replies
6
Views
2K
Replies
1
Views
2K
Replies
3
Views
1K
  • · Replies 5 ·
Replies
5
Views
2K
  • · Replies 75 ·
3
Replies
75
Views
6K
  • · Replies 17 ·
Replies
17
Views
2K
  • · Replies 9 ·
Replies
9
Views
2K
  • · Replies 6 ·
Replies
6
Views
4K