Question about the efficiency of using an array or individual variables

In summary, the conversation discusses the efficiency of using array A[10] versus individual variables B(0..9) in a program. The individual variables may be faster due to their one-step access, while the array requires additional steps to access the desired value. The conversation also touches on the limitations of declaring arrays with a constant size and the use of vector as a workaround. Finally, the conversation explains the difference in initialization between {1} and {1, 1, 1, 1, 1, 1, 1, 1, 1, 1} for an array of boolean values.
  • #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
Technology news on Phys.org
  • #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);
    cout << " The size of vector SA = " << SA.size()<< "\n\n";
    cout << " SA = {";
    for (int i = 0; i < sz; i++)
        cout << SA[i] << " ";
    cout << "} \n\n";
    sortAr(SA, sz);
    cout << " The numbers after sorting of vector SA = ";
    cout << " {";
    for (int i = 0; i < sz; i++)
        cout << SA[i] << " ";
    cout << "} \n\n";
    return 0;
}
void InputAr(vector<int>&Av, int &size)
{
    int num;
    do
    {
        cout << " Enter any +ve integer to be sorted, enter -1 to quit "; cin >> num;
        if (num >= 0)
            Av.push_back(num);
    } while (num >= 0);
    cout << "\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
    {
        cout << " 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::cout << 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
    cout << "In main return from getnumSold Sold = {";
    for (int i = 0; i < 9; i++)
        cout << Sold[i] << " ";
    cout << "} \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
        cout << " In getnumSold, You chose to use default = {";
        for (row = 1; row < DefaultNSold.size(); row++)
        {
            cout << 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++)
        {
            cout << 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++) {
        cout << 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++)
        {
            cout << 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++) {
        cout << 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());//recieve number sold for each item.
    getnumSold(Sold);//passing vector Sold to function getnumSold().
    cout << "In main return from getnumSold Sold = {";
    for (int i = 0; i < 9; i++)
        cout << Sold[i] << " ";
    cout << "} \n\n";
    return 0;
}void getnumSold(vector<int>& numSold)
{

    {
        int row;
        vector<int>numSold(DefaultNSold);
        cout << " In getnumSold, You chose to use default = {";
        for (row = 1; row < DefaultNSold.size(); row++)
        {
            cout << numSold[row - 1] << " ";
        }
        cout << 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());//recieve number sold for each item.
    int partNum;// part number of the book from customer.
    getnumSold(Sold);//passing vector Sold to function getnumSold().
    cout << "In main return from getnumSold Sold = {";
    for (int i = 0; i < 9; i++)
        cout << Sold[i] << " ";
    cout << "} \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.
{
    cout << 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++)
    {
        cout << "  " << 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;
    cout << " Enter y to use default numbers, any other character";
    cout << "for entering 6 new numbers: "; cin >> select;
    if ((select == 'y') || (select == 'Y'))
    {
        int row=1;
        vector<int>numSold(DefaultNSold);  
        cout << " In getnumSold, You chose to use default = {";
        for (row = 1; row < DefaultNSold.size(); row++)
        {
            cout << numSold[row - 1] << " ";
        }
        cout << numSold[row - 1] << "}\n\n";
    }
    else
    {
        cout << " You chose to enter 9 new sales number.\n\n";
        cout << "Enter number sold for the following\n\n";
        for (int row = 1; row <= DefaultNSold.size(); row++)
        {
            cout << "   " << 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());//recieve number sold for each item.
    getnumSold(Sold);//passing vector Sold to function getnumSold().
    cout << "In main return from getnumSold Sold = {";
    for (int i = 0; i < 9; i++)
        cout << Sold[i] << " ";
    cout << "} \n\n";
    return 0;
}void getnumSold(vector<int>& numSold)
{
int row = 1;
cout << " In getnumSold, You chose to use default = {";
for (row = 1; row < DefaultNSold.size(); row++)
{
    numSold[row - 1] = DefaultNSold[row - 1];
    cout << numSold[row - 1] << " ";
}
numSold[row - 1] = DefaultNSold[row - 1];
cout << 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++) {
        cout << numSold[row] << " ";
    }
    cout << 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.
 
  • #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++) {
        cout << numSold[row] << " ";
    }
    cout << 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.
 
  • #61
One reason for code bloat is the use of libraries that do what you want and more. Unfortunately, sometimes you can't just discard the more part.

One example from my recent past is developing code in python using Anaconda. Python modules call in other python modules so while you may want some particular function in a given module. It will pull in other modules you don't need.

The upside of using other peoples code is that you don't have to write it only use it as it probably had better testing done depending on its maturity of course.

We code to fit into the hardware we have and if we need a lot less memory then it can be engineered out of the final product. But wait, we may need to patch or update the code and we may need that memory that was removed so we must balance out our tradeoffs.

The old programming mantra still holds:
_ I can make it fast
- I can make it cheap
- I can make it reliable

pick any two and let me know.

Of course, bosses today will pick two and then ding you on the one they didn't choose.

Its good that you have an engineering background but sometimes that will get in the way of software development.

On one project I worked on, the engineers saved money on a signal pattern generator for high speed memory testing by packing the internal looping code ie by using 14 bit counters in one place and 12 bit in another...

It was a bear for programmers to build loop code loads as we had to constantly pack stuff up and decode errors returned to figure out what was happening during a test.

The hardware design didn't factor in the programmer's needs in the interest of getting the cheapest and fastest hardware possible.

I remember one hardware manager showing empathy to the programmers by saying he once wrote a BASIC program and can understand the difficulties we faced. We just looked at each other.

Some of the engineers in our group looked down on the programmers too. We needed to test a C based monitoring program that handled 200 sensors in a bay continuously for a few days. However, every morning we discovered it was swapped out for a PC BASIC program.

When asked why the engineers said our program ran too slow for their needs. Upon further investigation, we discovered that their program ran faster because it monitored only 20 sensors continuously. What a crock? Ours was configurable and could have done the same if they told us.

The payback came when they had some test program written in BASIC that exceeded 64K (PC-DOS BASIC limit) and they wanted our help to fix it. We suggested removing comments and other memory saving tricks but to no avail. Finally we said well I guess you'll have to recode it in C like we told you months ago. They were not happy campers after that.
 
  • #62
Ha, I never told programmers what to do, they tell me what they need and I design to fit their needs! They are the one that have to make the system work, Hardware part is only to support the system. Unless it is impossible for us to meet their needs, I always try to give them what they want. I sure did not tell them what language to write! What do I know!

I did a little assemble language programming long time ago, at least I know enough how to design hardware to make lives easier for people that are going to program it. Remember, we can make the most reliable hardware, but if programmer cannot program it, it's still a big fat ZERO. So part of my task is to make programmers' lives easier if all possible. It was always very smooth, never ran into problem in that department.

My specialty is really analog, RF, low noise. I had to design MPU digital stuffs only because I was the only one that can do it. It's not like I did those every day. Just design when needed. I designed the hardware, wrote the specifications how to program it. Never once I heard back from the software people after I handed it over. Maybe I was lucky!
 
  • Like
Likes jedishrfu
  • #63
Back to the original question, is there any way to fix using function
void getnumSold( vector<int>&numSold) and use vector<int>numSold(DefaultNSold) to copy DefaultNSold into numSold and then allow main to access as reference?

thanks
 
  • #64
yungman said:
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?

What you did wrong is exactly what the error message said.

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?

What that does is not just copy. It is making a whole new vector, numSold (using the same name as the parameter, hence the error message). I think your confusion will be cleared up when you learn about classes. You didn't learn what a constructor is yet, and were using it without even knowing it, thinking it was something else.

Anyways, I guess this is what you wanted to do (use the assignment operator):

Code:
void getnumSold(vector<int>& numSold)
{
    numSold = DefaultNumSold;
}

Also, it might be a good time to do a google search: "why are global variables considered bad programming practice".
 
Last edited:
  • #65
I put in the line you suggested, it's NOT working, it won't even compile. Also, I specifically asked about how to use vector<int>numSold(defaultNSold) for copying. I know numSold was defined TWICE, one in the function declaration, one in vector<int>numSold(defaultNSold). But this is how the syntax has to be. I am not asking about the error information. I know what is the error. My question is HOW to fix it using vector<int>numSold(defaultNSold).

This is what you suggested, it won't compile. I know how to fix the problem and I already fixed it using simple for loop.
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());//recieve number sold for each item.
    getnumSold(Sold);//passing vector Sold to function getnumSold().
    cout << "In main return from getnumSold Sold = {";
    for (int i = 0; i < 9; i++)
        cout << Sold[i] << " ";
    cout << "} \n\n";
    return 0;
}void getnumSold(vector<int>& numSold)
{
int row = 1;

    numSold = DefaultNumSold;

cout << " In getnumSold, You chose to use default = {";
for (row = 0; row < DefaultNSold.size(); row++)
{
    cout << DefaultNumSold[row] << " ";
}
cout << numSold[row] << "}\n\n";

}
 
  • #66
yungman said:
Because my syntax was not wrong.

I figured that much already.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?I want row to represent the real row number. The way I do works.
yungman said:
I put in the line you suggested, it's NOT working, it won't even compile. Also, I specifically asked about the code vector<int>numSold(defaultNSold) for copying. I know numSold was defined TWICE, one it the function declaration, one in vector<int>numSold(defaultNSold). But this is how the syntax has to be. I am not asking about the error information. I know what is the error. My question is HOW to fix it using vector<int>numSold(defaultNSold).

This is what you suggested, it won't compile.
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());//recieve number sold for each item.
    getnumSold(Sold);//passing vector Sold to function getnumSold().
    cout << "In main return from getnumSold Sold = {";
    for (int i = 0; i < 9; i++)
        cout << Sold[i] << " ";
    cout << "} \n\n";
    return 0;
}void getnumSold(vector<int>& numSold)
{
int row = 1;

    numSold = DefaultNumSold;

cout << " In getnumSold, You chose to use default = {";
for (row = 0; row < DefaultNSold.size(); row++)
{
    cout << DefaultNumSold[row] << " ";
}
cout << numSold[row] << "}\n\n";

}
What you are saying doesn't make any sense.
 
  • #67
Jarvis323 said:
What you are saying doesn't make any sense.
This is what you suggested to do: numSold = DefaultNumSold; It won't even compile.

I am not asking HOW to copy the vector from DefaultNSold to numSold, there are ways to do that. I specifically asked about using vector<int>numSold(defaultNSold) line to copy when passed to the function. This is in the book. It works if it is not passing into a function.

I already use a simple for loop to copy and completed the program already.

 
  • #68
yungman said:
This is what you suggested to do: numSold = DefaultNumSold; It won't even compile.

I am not asking HOW to copy the vector from DefaultNSold to numSold, there are ways to do that. I specifically asked about using vector<int>numSold(defaultNSold) line to copy when passed to the function. This is in the book. It works if it is not passing into a function.

I already use a simple for loop to copy and completed the program already.

If you read the error message of the new code where you used the assignment operator, you'll see that this is the error message.
Code:
prog.cpp:26:15: error: ‘DefaultNumSold’ was not declared in this scope
     numSold = DefaultNumSold;

It's because I wrote DefaultNumSold instead of DefaultNSold.

yungman said:
I specifically asked about using vector<int>numSold(defaultNSold) line to copy when passed to the function. This is in the book. It works if it is not passing into a function.

I already use a simple for loop to copy and completed the program already.

Like I said, that doesn't make sense at all. It isn't code for copying like you think it is, read my previous post again. Your problem is you don't understand what the line of code means. Once you understand what that code means, you'll realize your mistake and that it has nothing to do with it being passed to a function or not. Here is an equivalently wrong program without a function.

Code:
vector< int > x;
vector< int > &  y = x;
vector< int > y = default;

You need to slow down and learn what the code you are writing actually means, not just what you expect it to do.
 
Last edited:
  • Like
Likes pbuk
  • #69
Jarvis323 said:
Like I said, that doesn't make sense at all to do. Your problem is you don't understand what the line of code means, which I explained to you. Once you understand what that code means, you'll realize your mistake. It has nothing to do with it being passed to a function or not. Here is an equivalently wrong program without a function.

Code:
vector< int > x;
vector< int > &  y = x;
vector< int > y = default;
Jarvis323 said:
I understand the lines of code, I need to define the function
void getnumSold(vector<int>& numSold)

AND

I have to follow the instruction from the book vector<int>numSold(defaultNSold)

That defined the vector twice and thereby have the error. BUT I experimented the line of code vector<int>numSold(defaultNSold), it works as long as it's not passed to function. It WON'T work when passing the function.

These are very specific syntax and they don't work together. My question is how can I make this work. NOT how to do it.
 
  • #70
You can't make it work because it doesn't make any sense. If you want a new variable, then just use a different name. It won't be the same variable of course. It doesn't make a difference whether it's inside a function or not, you can't use the same name for two different variables. If it worked for you outside a function, then that's not what you did. Here are some examples.

C:
// this is wrong
vector< int > x;
vector< int > &  y = x;
vector< int > y( d ); // the name y is already used

// this is also wrong
vector< int > x;
vector< int > x; // the name x is already used

// this is also wrong
vector< int > x;
vector< int > x( d ); // the name x is already used

// this is also wrong
vector< int > x;
vector< int > x = d;// the name x is already used

// this is correct
vector< int > x = d;

// this is correct and exactly equivalent to the last version
vector< int > x (d);

// this is correct as well
vector< int > x;
x = d;

And it's not because it's a vector either.

C:
// this is wrong
int x;
int &  y = x;
int  y( d ); // the name y is already used

// this is also wrong
int x;
int x; // the name x is already used

// this is also wrong
int x;
int x( d ); // the name x is already used

// this is also wrong
int x;
int x = d;// the name x is already used

// this is correct
int x = d;

// this is correct
int x (d);

// this is correct as well
int x;
x = d;
 
Last edited:

Similar threads

Replies
7
Views
2K
Replies
6
Views
2K
Replies
1
Views
1K
Replies
5
Views
2K
Replies
75
Views
5K
Replies
17
Views
2K
Replies
9
Views
2K
Back
Top