Uninitialized local variable 'lc' used but I initialized it - c++

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.

Related

Make floor pattern

How do i make this?
image of my homework
note: Batasan means limitaion and Contoh means example
So, my professor wants me to do make output the same size horizontal and vertically in pattern shown in the image
I dont know what to do, but the best i can make is this:
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
const char * array1[4];
const char * array2[4];
array1[0] = "O", array1[1] = ">", array1[2] = "X", array1[3] = "<";
array2[0] = "v", array2[1] = "/", array2[2] = "^", array2[3] = "\\";
cin>>n;
for(int i = 1; i <= n; i++){
if (i%2 != 0){
for(int j = 0; j <=n; j++){
cout << array1[j];
}
cout<<"\n";
} else if (i%2 != 0) {
for(int j = 0; j <=n; j++){
cout << array2[j];
}
cout<<"\n";
}
return 0;
}
}
I dont know if array is necessary or not.
If you guys have any suggestion about my program feel free to give me some.
This is my first time asking in this web and im sorry if my post and english are terrible
Thanks in advance:)
We are here to help.
I will first show you the problems in your code and then make a proposal on how to make it better.
So, let us first check your code:
#include<bits/stdc++.h> is a non C++ compliant compiler extension. It should never be used. On my machine, it does not compile.
using namespace std; should not be used. It is better to always use full qualified names. This will avoid name clashes from different scopes or namespaces
Variables should have meaningful names. One character variables are in most cases not that good
All variables should be initialized during definition
C-Style arrays should not be used in C++. Always use a specialized STL container like std::vector or std::array
In C++ we use std::string for strings and not char[] or char *
Array indices in C/C++ start with 0. If you use <= in the end condition of a for loop, you will access an element one past the end. This is a severe out of bound error. You do that in you for loop with the 'j'
There is anyway a severe out of bound bug here. You access array[j] and j might be 4 or bigger. That is a bug and must be corrected. You can simply do a modulo devision % by 4. Then you do never exceed the 4. it will then always be 0,1,2,3,0,1,2,3,0,1,2,3 . . .
You should write as much as possible comments
If we correct all this findings, then we could come up with:
#include <array>
#include <iostream>
constexpr size_t NumberOfLinePatterns = 2;
constexpr size_t NumberOfElementsPerLinePattern = 4;
using Pattern = std::array<std::array<char, NumberOfElementsPerLinePattern>, NumberOfLinePatterns>;
// If you do not yet know the std::array. Then uncomment the following and
// remove on opening and closing curly brace in the initialization below
// using Pattern = char[NumberOfLinePatterns][NumberOfElementsPerLinePattern];
Pattern pattern{{
{'O','>','X','<'},
{'v','/','^','\\'}
}};
int main() {
// Get number of rows and columns to print
unsigned int numberOfElements{}; std::cin >> numberOfElements;
// Now, for all rows and columns
for (unsigned int row{}; row < numberOfElements; ++row) {
for (unsigned int column{}; column < numberOfElements; ++column) {
// Print the selected character
std::cout << pattern[row % NumberOfLinePatterns][column % NumberOfElementsPerLinePattern];
}
std::cout << '\n';
}
return 0;
}

How to add every element in a matrix?

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;

Issues with checking an array moving both forwards and backwards simultaneously and issue printing values stored in a pointer array

Preface: Currently reteaching myself C++ so please excuse some of my ignorance.
The challenge I was given was to write a program to search through a static array with a function and return the indices of the number you were searching for. This only required 1 function and minimal effort so I decided to make it more "complicated" to practice more of the things I have learned thus far. I succeeded for the most part, but I'm having issues with my if statements within my for loop. I want them to check 2 separate spots within the array passed to it, but it is checking the same indices for both of them. I also cannot seem to get the indices as an output. I can get the correct number of memory locations, but not the correct values. My code is somewhat cluttered and I understand there are more efficient ways to do this. I would love to be shown these ways as well, but I would also like to understand where my error is and how to fix it. Also, I know 5 won't always be present within the array since I'm using a pseudo random number generator.
Thank you in advance.
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
// This is supposed to walk throught the array both backwards and forwards checking for the value entered and
// incrementing the count so you know the size of the array you need to create in the next function.
int test(int A[], int size, int number) {
int count = 0;
for (int i = 0; i <= size; i++, size--)
{
if (A[i] == number)
count++;
// Does not walk backwards through the array. Why?
if (A[size] == number)
count++;
}
cout << "Count is: " << count << endl;
return (count);
}
// This is a linear search that creates a pointer array from the previous "count" variable in function test.
// It should store the indices of the value you are searching for in this newly created array.
int * search(int A[], int size, int number, int arr_size){
int *p = new int[arr_size];
int count =0;
for(int i = 0; i < size; i++){
if(A[i]==number) {
p[count] = i;
}
count++;
}
return p;
}
int main(){
// Initializing the array to zero just to be safe
int arr[99]={0},x;
srand(time(0));
// Populating the array with random numbers in between 1-100
for (int i = 0; i < 100; i++)
arr[i]= (rand()%100 + 1);
// Was using this to check if the variable was actually in the array.
// for(int x : arr)
// cout << x << " ";
// Selecting the number you wish to search for.
// cout << "Enter the number you wish to search for between 1 and 100: ";
// cin >> x;
// Just using 5 as a test case.
x = 5;
// This returns the number of instances it finds the number you're looking for
int count = test(arr, (sizeof(arr)/4), x);
// If your count returns 0 that means the number wasn't found so no need to continue.
if(count == 0){
cout << "Your number was not found " << endl;
return 0;
}
// This should return the address array created in the function "search"
int *index = search(arr, (sizeof(arr)/4), x, count);
// This should increment through the array which address you assigned to index.
for(int i=0; i < count; i++) {
// I can get the correct number of addresses based on count, just not the indices themselves.
cout << &index[i] << " " << endl;
}
return 0;
}
I deeply appreciate your help and patience as well as I want to thank you again for your help.

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.

What is wrong with the logic in my program?

I've been tasked to create a function that identifies the number of occurrences in an array, however i am not getting the correct result. This is the function i wrote, i left out the rest of the program as that works.
int countOccurences(int b[], int size, int x)
{
int occ = x;
for(int i = 0; i < size; i++)
{
if(b[i] == occ)
occ++;
}
cout << occ << endl;
return occ;
}
If occ is meant to be the number of occurrences, it should be initialised to zero rather than x.
And the comparison should be between b[i] and x, not b[i] and occ.
And, as an aside (not affecting your actual logic), it's also very unusual to actually print out the return value in a utility function which is obviously meant to simply return the count but it may be you have that in there just for debug purposes.
And you should both ensure your indentation and use of braces is consistent between your for and your if - it will make your code easier to maintain.
That's all totally aside from the fact that C++ possesses a std::count() method in <algorithm> that will work this out for you without having to write a function to do it (although it may be that this is an educational question and the intent is to learn how to code things like this, rather than use readily made library functions to do the heavy lifting for you).
int countOccurences(int b[], const unsigned int size, const int x)
{
int occ = 0;
for(unsigned int i = 0; i < size; i++)
{
if(b[i] == x)
{
occ++;
}
}
std::cout << occ << std::endl;
return occ;
}
occ should start at zero
You should compare b[i] to x
Array indices should be unsigned
Why not be const-correct?
using namespace std; is bad practice