Using loop variables as indices of a C++ array [closed] - c++

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I don't understand this, the part where it says, "myArray[x] = 42;"
Since when did x even come into myArray? Atleast someone explain me how this script even works?
{ int = myArray[5];
for (int x = 0; x < 5; x++) {
myArray[x] = 42;
cout << x << ":" << myArray[x] << endl;
}
}

C++ arrays are random-access containers. That means that if you want the ith element of the array, you can ask for it (and get it in constant time).
The operator used for array element access is the brackets ([]) operator. It takes a parameter of type std::size_t, which is a typedef to some unsigned integer type that's big enough to index all the memory addresses of your computer's RAM. Thus, if I have an array arr, and I index into it by writing arr[2], I'm asking for the second element of the array.
In the following example, an array is created, and each element is assigned a value equal to the square of its index.
#include <cstdlib>
#include <iostream>
int main() {
constexpr std::size_t length = 10;
int arr[length];
for (std::size_t i = 0; i < length; ++i) {
arr[i] = i * i;
std::cout << "Element " << i << " of arr is " << arr[i] << "." << std::endl;
}
}
Because operator[] returns a reference (in this case an int&), the expression arr[i] can be used for both reading and writing the value.

I'll be specific here, you need to read on basic programming in c++, because you are questioning the fundamental ways the for-loop in c++ works.
I will start by formatting your code so that is is easier to read:
{
int = myArray[5];
for (int x = 0; x < 5; x++)
{
myArray[x] = 42;
cout << x << ":" << myArray[x] << endl;
}
}
Let me point out some errors in your code. Firstly, when you declare a variable in c++, you must also declare its data type along with it. So the following example:
var = 2;
Is invalid, because the data type of the variable var is not specified. The compiler cannot tell what the data type of a variable is by simply looking at the value passed to it in c++. Therefore, we need to add the data type just before the name of the variable when DCLARING IT ONLY. So in the above example:
int var = 2;
Is a valid variable declaration because we have specified that this variable will only store an int value.
Now the problem in your code is that you are trying to do:
int = myArray[5];
This makes no sense. First problem is that you are trying to assign a data type a value as if it were a variable. Second problem is that you never declared myArray before. From your cod, I'm assuming that you intended to do:
int myArray[5];
This makes sense because your for-loop also runs 5 times. In this line, you have declared an array called myArray that stores 5 values of type int.
Now moving on to the for-loop. Lets dissect the header statement of the for-loop:
for (int x = 0; x < 5; x++)
The first statement right after the opening semicolon int x = 0; simply declares a variable ONCE for the entire run of the for loop. This variable x is local to the for loop and cannot ba accessed outside of it. In c++, we refer to it as a counter variable as it stores the number of times we have gone looped through a for-loop.
The next statement x < 5; is a condition for the for-loop. While this condition is true, the for-loop will run; In your case, while x is less than 5, it will run through the loop. As soon as this condition become false; in this code, if x becomes equal to or greater than 5, then the condition is falsified, and the loop is terminated. This way, we ensure that the loop runs through our code only the number of times we want it to.
The final statement x++; simply means that x is incremented at every point. If it is not incremented, then the value of x will never change, and the condition of the loop will never be falsified, making it an infinite loop. Therefore, this statement is crucial.
Now while we are inside the for-loop, we can use the variable x. This is particularily useful in your case as you have an array, and you are trying to fill it up with values. Instead of doing array[a]=n, where a ranges from 0 up till the size of the array minus 1, and n is a random number, we can use a for loop to initialize our values.
In the for loop, how do we do that? We use the counter x, that increments itself after every loop run, to serve as the "a" in array[a]. That's why we use myArray[x] = 42;, simply because x increments itself by 1 after every loop and this number can be used as the address (sorry for my poor choice of words here) of the array. Why it allocates the number 42 is random; it could allocate any number.
If you still need some clarification, or if I made a mistake in my post, please let me know in the comments box.

Related

the largest element in the array outputs as -858993460 [C++]

im trying to let the user input a number for each person. the console then outputs the maximum value in the array. everything works fine but the max always outputs as -858993460. i tried multiple combinations but i cant seem to figure it out
im new to arrays so any help would be appreciated as well as an feedback on how to improve my code
#include <iostream>
int main()
{
int people[10];
int max = people[0];
std::cout << "please enter number of pancakes eaten by each person.\n";
//lets the user input values for each element
for (int i = 0; i < 10; ++i) {
std::cin >> people[i];
}
//outputs all the elements of the array
for (int i = 0; i < 10; ++i) {
std::cout << people[i] << " ";
}
//finds the largest element in the array
for (int i = 0; i > 10; ++i) {
if (people[i] > max) {
max = people[i];
}
}
std::cout << "\nmax: " << max;
return 0;
}
also i keep getting a warning saying: ill-defined for-loop. loop body not executed. i tried looking this warning up but the warning seems very broad and i couldnt find anything that helped
int people[10];
This declares an array of ten int values. None of the values are explicitly initialized. This is how plain values that get declared in automatic scope work in C++, they are not initialized to any values. It is the code's responsibility to initialize them.
int max = people[0];
This sets the value of max to the first value of the array. Which has not been initialized to any value. This is undefined behavior. From this point on the program's behavior is undefined.
Furthermore, even if peoples values were initialized this will still be broken. The intent of the program is clear: read values into the people array, and then find their maximum value.
However, at this point, nothing has been read from anywhere.
The attempted goal here is to set max, initially, to the first value in the array, the first read value.
But in order for this to make sense, max should be set after the values in the array get read from input, and not before. This should be done after all the values are read in, and not before.
in the line int max = people[0] you are dereferencing the first element of the array. But dereferencing to what? at that point in the program you have not initialised any of the 10 elements in the people array. So taking the value at people[0] at that point in the program and copying it into another int for later comparison is undefined behaviour. Best solution is to simply move int max = people[0] to after you take the user input, and for the comparison loop start with i = 1, because max is already equivalent to the first inputted value.

I am unable to assign difference of two elements of 2 dimensional array to element of other array in C++? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
Below is the code, which is breaking my head since two days.
#include <iostream>
using namespace std;
int main()
{
int N;
int A[1][N-1];
int B[1][N-1];
std::cout << "ENTER NO OF ROUND" << '\n';
std::cin >> N;
for (int j=0; j<N; j++)
{
int i =0;
std::cout << "enter the scores" << '\n';
std::cin >> A[i][j]>>A[i+1][j];
if (A[i][j] > A[i+1][j])
{
B[i][j] = A[i][j] - A[i+1][j];
B[i+1][j] = 1;
}
if (A[i][j] < A[i+1][j])
{
B[i][j] = A[i+1][j] - A[i][j];
B[i+1][j] = 2;
}
}
std::cout << A[0][0]<<A[1][0] << '\n';
return 0;
}
Here in line 18 line 19 and line23 line24i should get difference of two elements of array A[1][N-1] Which is then assigned to a element in array B[1][N-1],but am unable get the correct result ,rather am getting a random number.
help me getting through this
You use uninitialized data, so anything can happen.
You declare the N variable:
int N;
And then, in the very next line, without assigning any value, you use it to create two arrays using N as a size:
int A[1][N-1];
int B[1][N-1];
This already is a starting point for disaster. Moreover, declaring an array with size [N - 1] is not technically correct - N is a variable, so cannot be used to declare array in this manner. It's a compiler extension (are you using Visual Studio?). If value of N is known, declare it as:
static constexpr size_t N = value;
If it is read at runtime, create your arrays with new or, much better, use std::vector to make your code robust and less error-prone.
The second thing is, that A array is declared as int A[1][N-1];, but you do the following:
int i = 0;
....
if (A[i][j] > A[i+1][j])
Which results in reading A[1][j], which does not exist - in C++ we start indexing from 0! You also modify those non-existing elements:
std::cin >> A[i][j] >> A[i+1][j];
which most likely will result in writing to memory that belongs to B array.
Small notes:
using namespace std seems redundant, as you write std:: everywhere
what is the point of two-dimensional array [M][N] if M = 1?
Use std::vectors if you need arrays with size determined at run-time. The C Variable-length arrays you use are not supported in C++.
std::cout << "ENTER NO OF ROUND" << '\n';
int N = 0;
std::cin >> N;
std::vector<std::vector<int>> A(2, std::vector<int>(N));
std::vector<std::vector<int>> B(2, std::vector<int>(N));
And note that you need 2 x N array because you read both A[i][j] and A[i+1][j] and your for loop is from [0 to N-1] -- N times.

C++ why struct object values reset back to ZERO at end of loop

I created a simple struct object that holds 2 values - number (specific number) and count (counter for how many times number appears).
typedef struct matrixMissNumber {
int number;
int count = 0;
}
Then I created a list called, missingNumsObjects, to hold those objects. missNums is a seprate list that simply holds ints.
list<matrixMissNumber> missingNumsObjects;
for (auto m : missNums)
{
matrixMissNumber mn;
mn.number = m;
missingNumsObjects.push_back(mn);
}
I then have 3 for-loops that go through and check 2 conditions. If those conditions are satisfied, count increments by 1. (I added a cout statement for testing purposes). I debugged the program and everything works perfectly, until the loops end. That's when the count variable for every matrixMissNumber object in missingNumsObjects resets back to 0. I'm not sure if its a problem where different memory addresses are being manipulated, or lists pointers that are the issue.
for (auto m : missingNumsObjects)
{
for (int x = 0; x < 3; x++)
{
for (int y = 0; y < 3; y++)
{
if (sudoku[x][y] == 0)
{
if (checkRowRule(m.number, x) == false && checkColumnRule(m.number, y) == false)
{
m.count++;
cout << m.number << " - " << m.count << endl;
}
}
}
}
}
The next lines print out the values of count of the missingNumsObjects after the loop. This is where the values return back to 0.
for (auto m : missingNumsObjects)
cout << m.number << " - " << m.count << endl;
This program's purpose is a Sudoku Solver. This part of the algorithm checks the 3x3 matrix for missing numbers and checks into how many empty spots in the 3x3 matrix that number can go into.
for (auto m : missingNumsObjects)
Here auto is deduced as matrixMissNumber, so m is a copy of matrixMissNumber object stored in the list. Then you change the copy, not the object in the list missingNumsObjects.
To fix the issue help the compiler to deduce the type properly and change the cycle to:
for (auto& m : missingNumsObjects)
The problem you'll gain the most from is actually here
"I debugged the program and everything works perfectly, until the
loops end".
Things weren't working perfectly until the loop finished. You never inspected the contents of the list as had you done so, you'd have noticed that it never changed.
The moral of this is that when debugging, inspect the thing that should be changing, not what you're assigning to.

How to write a C++ array printing loop that starts at a different point on each iteration?

I have a struct that has two member variables, each is an int.
struct trash
{
int sector;
int weight;
};
I have an array where each element contains one of these structs. All of the data is randomly generated within a set range. In this case, sectors are generated randomly from 1-7. Also, the array is size 15 in this instance. So each sector has a random number of weight variables associated with it. What I am trying to accomplish is printing out what piles belong to each sector. So the format should look like this
Sector 1
Pile 1: xxx
Pile 2: xxx
...
Sector 2
Pile 1: xxx
....
Sector 7
and so on if that makes sense
My attempt at this so far was to sort the array of structs by sector from least to greatest first and then print out the weight variable of each by iterating over the array using for loops. In a nutshell, I just want to print out the array in order after it is sorted by sector but break it up by sector. I can't for the life of me seem to figure out how to accomplish this in a compact, concise way. Below is the loop I have written now that doesnt quite work because the inner loop starts at the same point each time.
for(int i=0;i<NUM_SEC;i++)
{
cout<<"Sector "<<(i+1)<<endl;
for(int j=0;j<num_piles[i];j++)
{
cout<<"Pile "<<(j+1)<<": "<<data[j].weight<<endl;
cout<<endl;
}
}
Any tips would be appreciated, I've already spent hours on just this small aspect of the program and its very frustrating.
Looks like you want to access not data[j], but data[j + previous_piles]. You could then do something like:
int previous_piles = 0;
for(int i=0;i<NUM_SEC;i++)
{
cout<<"Sector "<<(i+1)<<endl;
for(int j=0;j<num_piles[i];j++)
{
cout<<"Pile "<<(j+1)<<": "<<data[j+previous_piles].weight<<endl;
cout<<endl;
}
previous_piles += num_piles[i];
}
You are not keeping record of your progress!!
Look at the following code:
int last_pile = 0; // will keep track of the last printed index
for(int i=0;i<NUM_SEC;i++)
{
cout<<"Sector "<<(i+1)<<endl;
for( int j = 0; j < num_piles[i]; j++)
{
cout << "Pile " << (j+1) << ": " << data[j+last_pile].weight << endl; // sum last_pile to j
}
// updated last printed index
last_pile += num_piles[i];
cout << endl; // empty line 'cause finihes with this sector
}
I created a new variable last_pile which will store the last visited index. Then, inside the loop, I add the value of this variable to the sub-index j so you always get the correct element from the array.
Please pay attention to the comment, I added useful information there.

creating mxn 2D array in c++ without using any external library

I am a beginner to C++ syntax. Now, I need to create an mxn 2D array in C++ to use it in another project. I have looked at other answers which involve using tools like vector, etc. Many tools are not working on my Visual Studio 15 i.e. for vector I can not define with std::vector without a message like vector is not in std. So, I have wrote the following code:
#include "stdafx.h"
#include <iostream>
using namespace std;
int main()
{
int i; int j; int row[5][10] = {};
for (int j = 0; j < 10;)
for (int i = 0; i < 5;)
{
row[i][j] = 500;
int printf(row[i][j]);
i++;
j++;
cout << "Array:" << row[i][j] << endl;
}
return 0;
}
Surely, this is not the correct syntax. So the output is beyond my expectation. I want to create an m*n array with all the elements being the same integer; 500 in this case. That is, if m=3, n=2, I should get
500 500 500
500 500 500
There's a couple things wrong with your current code.
The first for loop is missing curly brackets
You're redefining int i and int j in your for loop. Not a complilation issue but still an issue.
You're using printf incorrectly. printf is used to output strings to the console. The correct line would be printf("%d", row[i][j]);
If you want to use a vector, you have to include it using #include <vector>. You can use a vector very similar to an array, but you don't have to worry about size.
You seem to be learning. So, I did minimal correctios to make it work. I suggest you to make modifications as per your needs.
#include <iostream>
using namespace std;
int main()
{
int row[5][10] = {};
for (int j = 0; j < 10; j++) {
for (int i = 0; i < 5; i++) {
row[i][j] = 500;
cout << row[i][j] << " ";
}
cout << endl;
}
return 0;
}
Care and feeding of std::vector using OP's program as an example.
#include <iostream>
#include <vector> // needed to get the code that makes the vector work
int main()
{
int m, n; // declare m and n to hold the dimensions of the vector
if (std::cin >> m >> n) // get m and n from user
{ // m and n are good we can continue. Well sort of good. The user could
// type insane numbers that will explode the vector, but at least they
// are numbers.
// Always test ALL user input before you use it. Users are malicious
// and incompetent <expletive delteted>s, so never trust them.
// That said, input validation is a long topic and out of scope for this
// answer, so I'm going to let trapping bad numbers pass in the interests
// of keeping it simple
// declare row as a vector of vectors
std::vector<std::vector<int>> row(m, std::vector<int> (n, 500));
// breaking this down:
// std::vector<std::vector<int>> row
// row is a vector of vectors of ints
// row(m, std::vector<int> (n, 500));
// row's outer vector is m std::vector<int>s constructed with
// n ints all set to 500
for (int j = 0; j < n; j++) // note: j++ has been moved here. This is
// exactly what the third part of a for
// statement is for. Less surprises for
// everyone this way
// note to purists. I'm ignoring the possible advantages of ++j because
// explaining them would muddy the answer.
// Another note: This will output the transverse of row because of the
// ordering of i and j;
{
for (int i = 0; i < m; i++) // ditto I++ here
{
// there is no need to assign anything here. The vector did
// it for us
std::cout << " " << row[i][j]; // moved the line ending so that
// the line isn't ended with
// every column
}
std::cout << '\n'; // end the line on the end of a row
// Note: I also changed the type of line ending. endl ends the line
// AND writes the contents of the output stream to whatever media
// the stream represents (in this case the console) rather than
// buffering the stream and writing at a more opportune time. Too
// much endl can be a performance killer, so use it sparingly and
// almost certainly not in a loop
}
std::cout << std::endl; // ending the line again to demonstrate a better
// placement of endl. The stream is only forced
// to flush once, right at the end of the
// program
// even this may be redundant as the stream will
// flush when the program exits, assuming the
// program does not crash on exit.
}
else
{ // let the use know the input was not accepted. Prompt feedback is good
// otherwise the user may assume everything worked, or in the case of a
// long program, assume that it crashed or is misbehaving and terminate
// the program.
std::cout << "Bad input. Program exiting" << std::endl;
}
return 0;
}
One performance note a vector of vectors does not provide one long block of memory. It provides M+1 blocks of memory that may be anywhere in storage. Normally when a modern CPU reads a value from memory, it also reads values around it off the assumption that if you want the item at location X, you'll probably want the value at location X+1 shortly after. This allows the CPU to load up, "cache", many values at once. This doesn't work if you have to jump around through memory. This means the CPU may find itself spending more time retrieving parts of a vector of vectors than it does processing a vector of vectors. The typical solution is to fake a 2D data structure with a 1D structure and perform the 2D to 1D mapping yourself.
So:
std::vector<int> row(m*n, 500);
Much nicer looking, yes? Access looks a bit uglier, though
std::cout << " " << row[i * n + j];
Fun thing is, the work done behind the scenes converting row[j][i] to a memory address is almost identical to row[j*n+i] so even though you show more work, it doesn't take any longer. Add to this the benefits you get from the CPU successfully predicting and reading ahead and your program is often vastly faster.