How to add every element in a matrix? - c++

I am trying too add every element in a int matrix so I can check if the player or computer wins.
bool WinCondition(int Grid[10][10])
{
int SumOfShips;
for (int a = 0; a < 10; a++)
{
for (int b = 0; b < 10; b++)
{
SumOfShips += Grid[a][b] ;
if (SumOfShips == 30) return true;
}
}
return false;
}
However "+=" isn't working for me neither is . . . = Grid[a][b] + SumOfShips, I am getting the error "unititialized local variable 'SumOfShips' used"

You need to have int SumOfShips = 0; or some initial value, which makes sense in the context.
The reason being, that SumOfShips, when not initialized holds an arbitrary (indeterminate) value given the randomly assigned memory location.
Further, the uninitialized value is regarded as being 'indeterminate', check here for a more thorough explanation.

As the message says, the variable SumOfShips is used without being initialized.
Initialize that like this:
int SumOfShips = 0;
instead of:
int SumOfShips;

Related

My array is gettting an error because it's being defined as a singular integer

The point of this program is to output whether a series of digits (the number of digits undefined) is sorted or not (largest to smallest or smallest to largest).
I have defined my array in my function parameter, and I am trying to use a for loop to store the user's input, as long as it is above 0, in said array.
However, I am getting the error argument of type int is incompatible with parameter of type int*.
The exact error is the argument of type int is incompatible with parameter of type int*.
It is referring to line 22 and 23, these two;
isSorted(list[2000]); and
bool is = isSorted(list[2000]);.
I know this means my for loop is assigning a single value to my variable repeatedly from reading similar questions however I can not figure out how to fix this.
#include <iostream>
using namespace std;
bool isSorted(int list[]);
int main()
{
int i;
int list[2000];
int k = 0;
for (i = 0; i < 2000; i++)
{
int j;
while (j > 0)
{
cin >> j;
list[i] = j;
}
}
isSorted(list[2000]);
bool is = isSorted(list[2000]);
if (is == true)
cout << "sorted";
else
cout << "unsorted";
return 0;
}
bool isSorted(int list[])
{
int i = 0;
for (i = 0; i < 2000; i++)
{
if (list[i] > list[i + 1] || list[i] < list[i - 1])
{
return false;
}
else
return true;
}
}
I removed unused variable k.
Made 2000 parameterized (and set to 5 for testing).
In isSorted you are not allowed to return
true in the else as if your first element test would end in else you would return true immediately not testing other elements. But those later elements can be unsorted as well.
In isSorted you are not allowed to run the loop as for(i = 0; i < 2000; i++), because you add inside the for loop 1 to i and end up querying for i == 1999 list[2000], which is element number 2001 and not inside your array. This is correct instead: for (i = 0; i < 1999; i++). You also do not need to check into both directions.
You cannot call isSorted(list[2000]) as this would call is sorted with an int and not an int array as parameter.
You write int j without initializing it and then query while j > 0 before you cin << j. This is undefined behaviour, while most likely j will be zero, there is no guarantee. But most likely you never enter the while loop and never do cin
I renamed the isSorted as you just check in your example for ascending order. If you want to check for descending order you are welcome to train your programming skills and implementing this yourself.
Here is the code with the fixes:
#include <iostream>
using namespace std;
bool isSortedInAscendingOrder(int list[]);
const int size = 5; // Set this to 2000 again if you want
int main()
{
int i;
int list[size];
for (i = 0; i < size; i++)
{
int j = 0;
while(j <= 0)
{
cin >> j;
if(j <= 0)
cout << "rejected as equal or smaller zero" << endl;
}
list[i] = j;
}
if (isSortedInAscendingOrder(list))
cout << "sorted" << endl;
else
cout << "unsorted" << endl;
return 0;
}
bool isSortedInAscendingOrder(int list[])
{
for (int i = 0; i < size -1; i++)
{
if (list[i] > list[i + 1])
{
return false;
}
}
return true;
}
This is a definition of an array of 2000 integers.
int list[2000];
This is reading the 2000th entry in that array and undefined, because the highest legal index to access is 1999. Remember that the first legal index is 0.
list[2000]
So yes, from point of view of the compiler, the following only gives a single integer on top of being undefined behaviour (i.e. "evil").
isSorted(list[2000]);
You probably should change to this, in order to fix the immediate problem - and get quite close to what you probably want. It names the whole array as parameter. It will decay to a pointer to int (among other things loosing the information of size, but you hardcoded that inside the function; better change that by the way).
isSorted(list);
Delete the ignored first occurence (the one alone on a line), keep the second (the one assigning to a bool variable).
On the other hand, the logic of a your sorting check is flawed, it will often access outside the array, for indexes 0 and 1999. I.e. at the start and end of your loop. You need to loop over slightly less than the whole array and only use one of the two conditions.
I.e. do
for (i = 1; i < 2000; i++)
{
if (list[i] < list[i - 1])
/* ... */
The logic for checking ascending or descending sorting would have to be more complex. The question is not asking to fix that logic, so I stick with fixing the issues according to the original version (which did not mention two-way-sorting).
You actually did not ask about fixing the logic for that. But here is a hint:
Either use two loops, which you can break from as soon as you find a conflict, but do not return from the fuction immediatly.
Or use one loop and keep a flag of whether ascending or descending order has been broken. Then return true if either flag is still clear (or both, in case of all identical values) or return false if both are set.

Uninitialized local variable 'lc' used but I initialized it

I wanted to check whether what I wrote on the programming exam was working at least. And it turned out that it was not. And I do not understand why EXACTLY it does not work.
The task was to write a program with boolean function which should return true state if 2d matrix has only one row which consist entirely of negative element.
Here is the code:
#include "stdafx.h"
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
bool cns();
const int n=5;
int a[n][n];
bool cns() {
int ts;
//!!!!
int lc; //!! I have initiated lc variable but still it does not work !!
//!!!
//standard 2d static quad matrix
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cout << "a[" << i << "][" << j << "]=" << endl;
cin >> a[i][j];
}
}
//check whether the sum of elements of the row is negative or not
for (int i = 0; i < n; i++) {
ts = 0; //temp sum
for (int j = 0; j < n; j++) {
ts += a[i][j]; //I thought what if sum of elements is negative then the whole row is negative too
if (ts < 0) { //I have just realized that is wrong
lc++; //counter of negative lines, which consist entirely of negative elements
}
}
}
//only one row should be whole negative
if (lc == 1) {
return true;
}
else {
return false;
}
}
int main()
{
int lc;
cout << cns << endl;
return 0;
}
So could you tell me please where I did mistake with variable 'lc' and why compiler tells me "uninitialized local variable 'lc' used"?
You haven't initialized lc, but declared it.
To initialize a variable means giving it an initial value (which you should always do):
int lc = 0;
Initialising a variable is, essentially, giving it an initial value.
Your definition of lc
int lc;
does not initialise it. Since it is a variable of automatic storage duration (i.e. it is local to a block), it is not initialised.
Accessing its value therefore gives undefined behaviour.
The first thing that the code does with lc (within the first set of loops in your code) is
lc++;
Incrementing a variable of type int requires accessing its value, before producing an effect (doing the act of incrementing). Hence undefined behaviour.
The compiler warning is being issued because of that. To eliminate the warning, either initialise it where it is defined. For example;
int lc = 42;
or ensure the first operation is to set it to a valid value
int lc;
// later on the first thing ever done to lc is ...
lc = 47;
People often assume that all variables (of basic types, like int) which are defined without being explicitly initialised will have an initial value of 0 (zero). That is true in some other languages, but not in C++ - at least not in this context (an int of static storage duration IS zero-initialised).
Initialization is not what you have done here. As stated by amc176 you have only declared it.
When you declare variable lc, memory is reserved on the stack. The amount of memory reserved depends on the data type (a char will take up more memory than an int).
However, if you do not provide an initial value for that variable (i.e. initialize it) the initial value of the data type will be exactly what was present in that specific piece of memory. That is why your compiler is complaining.

How do I get the number of variables alive in a for loop?

Consider the following piece of code:
int main() {
int a = 0;
int b = 1;
for (int i = 0; i < 3; i++) {
a = 2;
int c = 1;
int d = 3;
d = a + c;
}
a = b+2;
}
In the piece of code above three variables have a lifespan contained in the body of the loop (i, c and d). I would like to be able to count the variables whose lifespan exists in the body of any given loop using LLVM (i.e. for this loop, my code should return 3).
I found the Live Variables Analysis, but I'm having trouble using it to find what I described above.
Maybe this should just be a comment, but I couldn't express the code inline:
Only two variables have duration within the loop body. i is declared before the loop starts, and lasts until after the last execution of the loop body. In other words, c and d are constructed/destructed 3 times; after the third time they are destructed, then i is.
Thus, the for loop you wrote is equivalent to:
{
int i = 0;
while (i < 3)
{
a = 2;
int c = 1;
int d = 3;
d = a + c;
}
i++;
}
The extra set of braces invokes block scoping; i goes out of scope and is destroyed outside of the for loop body, but before any subsequent code.

c++ counting sort

I tried to write a countingsort, but there's some problem with it.
here's the code:
int *countSort(int* start, int* end, int maxvalue)
{
int *B = new int[(int)(end-start)];
int *C = new int[maxvalue];
for (int i = 0; i < maxvalue; i++)
{
*(C+i) = 0;
}
for (int *i = start; i < end; i++)
{
*(C+*i) += 1;
}
for (int i = 1; i < maxvalue-1 ; i++)
{
*(C+i) += *(C+i-1);
}
for (int *i = end-1; i > start-1; i--)
{
*(B+*(C+(*i))) = *i;
*(C+(*i)) -= 1;
}
return B;
}
In the last loop it throws an exception "Acces violation writing at location: -some ram address-"
Where did I go wrong?
for (int i = 1; i < maxvalue-1 ; i++)
That's the incorrect upper bound. You want to go from 1 to maxvalue.
for (int *i = end-1; i > start-1; i--)
{
*(B+*(C+(*i))) = *i;
*(C+(*i)) -= 1;
}
This loop is also completely incorrect. I don't know what it does, but a brief mental test shows that the first iteration sets the element of B at the index of the value of the last element in the array to the number of times it shows. I guarantee that that is not correct. The last loop should be something like:
int* out = B;
int j=0;
for (int i = 0; i < maxvalue; i++) { //for each value
for(j<C[i]; j++) { //for the number of times its in the source
*out = i; //add it to the output
++out; //in the next open slot
}
}
As a final note, why are you playing with pointers like that?
*(B + i) //is the same as
B[i] //and people will hate you less
*(B+*(C+(*i))) //is the same as
B[C[*i]]
Since you're using C++ anyway, why not simplify the code (dramatically) by using std::vector instead of dynamically allocated arrays (and leaking one in the process)?
std::vector<int>countSort(int* start, int* end, int maxvalue)
{
std::vector<int> B(end-start);
std::vector<int> C(maxvalue);
for (int *i = start; i < end; i++)
++C[*i];
// etc.
Other than that, the logic you're using doesn't make sense to me. I think to get a working result, you're probably best off sitting down with a sheet of paper and working out the steps you need to use. I've left the counting part in place above, because I believe that much is correct. I don't think the rest really is. I'll even give a rather simple hint: once you've done the counting, you can generate B (your result) based only on what you have in C -- you do not need to refer back to the original array at all. The easiest way to do it will normally use a nested loop. Also note that it's probably easier to reserve the space in B and use push_back to put the data in it, rather than setting its initial size.

c++ vector manipulation

I'm trying to remove the biggest int element in a vector and insert it into a new vector.I already have an int that represent the highest number in the vector and one that represents the position of that number.
Heres my code:
vector2.push_back(highest);
vector1[highestpos] = vector1[vector1.size()-1];
vector1[vector1.size()-1] = highest;
vector1.pop_back();
But it returns an error. Is there anything wrong with this code?
EDIT::::::HERE IS MORE OF MY CODE. The error I get is an assertion error that says vector subscript is out of range.
while(vector1.size() > 0)
{
highest = 0;
for (int i = 0; i < vector1.size(); i++)
{
if (vector1[i] > highest)
{
highest = vector1[i];
int highestpos = i;
}
}
vector2.push_back(highest);
vector1[highestpos] = vector1[vector1.size()-1];
vector1[vector1.size()-1] = highest;
vector1.pop_back();
}
Based on the edit, the problem is that the highestpos inside the loop, to which the value of i was assigned, is not the same as the highestpos outside the loop.
Try a std::cout << highestpos << '\n'; right before vector1[highestpos] = ...
(it may also be helpful to use max_element() instead of the hand-written loop to determine the highest value and vector1.erase() to delete from the vector, although erase may indeed be less efficient than swap+pop_back)
int highestpos = i;
You're just defining a variable inside the loop. It doesn't change the value of the variable outside the loop. Change to:
highestpos = i;