bool vs void vs print or std::cout [closed] - c++

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
What is the difference between having a void or a bool and why is the answer not displaying right? The more I look up and try to understand the deeper I dig myself into a whole. (eg: std::boolalpha)?!?
#include <iostream>
#include <stdio.h>
#include <vector>
bool findPair(int* arr, int arrLength, int k)
{
for(int i=0; i<arrLength; i++)
{
for(int j = i+1;j<arrLength; j++)
{
if(arr[i] + arr[j] == k)
{
printf("Pair Found (%d, %d)", arr[i], arr[j], "\n");
//return;
}
}
}
printf("Pair NOT Found!");
//return false;
}
int main()
{
int array[5] = {4,5,1,7,2};
int sum = 221;
int arrLength = sizeof(array)/sizeof(array[0]);
findPair(array, arrLength, sum);
std::cout << std::endl << findPair() << std::endl;
// return 0;
}
Gives the following output when a pair is found (int sum = 3;):
Pair Found (1, 2)Pair NOT Found!
1
And this output when the pair is not found (int sum = 221;):
Pair NOT Found!
1

Right now, you've told the compiler that findPair returns a bool, but the method doesn't actually return true or false. You've lied to the compiler, and the compiler is allowed to do whatever it wants in this case. A function with a return type should always have a return statement that tells the compiler what value to return to the caller (or throw an exception).
A method with a void return type does not have to have a return; statement, and it's return; statements do not have to return a value, but you can still use return; statements to tell the computer to stop executing the method and return to the caller.
In your case, since you've eliminated the return statement after "Pair Found (%d, %d)", the method keeps executing, until it reaches the end of the loop, which is why you see both printf statements execute. Make sure to put a return type there.
Separately, std::cout << findPair will try print the address of the function, but since there's no overload for that, it will convert the pointer to a boolean, thus printing 1. What you probably wanted was to store the returned value into a bool variable, and send that to cout?
If you want to output true or false instead of 1 or 0 for bool types, then stream out std::boolalpha first, as in std::cout << std::boolalpha << myBoolean;

Related

in c++ i get the error: cannot convert 'bool' to 'bool*' in return [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
Im new to c++ and im trying to get a bool* function with a dynamic array as its parameter and its size to return true or false when none of them is zero but im getting an error: cannot convert 'bool' to 'bool*' in return.
bool* noneZero(int *zero, int N) {
int PL = 0;
for (int i = 0; i < N; i++) {
if (i == 0) {
PL++;
}
}
if (PL == N)
return false; //cannot convert 'bool' to 'bool*' in return
else
return true; //cannot convert 'bool' to 'bool*' in return
}
int main(int argc, char** argv) {
int *z=new int[5]{0,0,0,0,0};
cout << noneZero(z,5);
}
Also the question is how the teacher gave it to me. we dont work with vectors. Basically i have to return false when all of the numbers in my dynamic array are 0 and true when they arent. My question is why i get an error: cannot convert 'bool' to 'bool*' in return
Frankly, there are many problems in your code and I suggest to start from scratch.
First, dynamic arrays in C++ are std::vector. You need a good reason to use something else.
Next, your function is too complicated. You need not count the number of zeros if all you want is to check if there is none or at least one:
bool noneZero(const std::vector<int>& in) {
for (size_t i=0; i< in.size(); ++i) { // a vector "knows" its size !
if ( in[i] == 0 ) return false; // no need to search further
}
return true;
}
int main() {
std::vector<int> z{1,2,3,4,5};
bool x = noneZero(z);
if (x) std::cout << "there is no 0 in the vector\n";
for (const auto& e : z) {
std::cout << e << " ";
}
}
A std::vector manages the memory for you, ie no need for manual new or delete. It is not clear why you use the pointer returned from the function as if it points to an array (it does not and your code has undefined behavior). I added a loop that prints the vectors elements.
Problem:
A bool* must return a pointer a pointer to a bool, not a bool itself.
You're checking the value of i, not the values of the array.
Solution:
Change the function from a bool* to a bool.
Change i == 0 to *(zero + i) == 0.
Additional information:
Seems like you're using using namespace std;. using namespace std; is considered a bad practice (More info here).
You probably should use std::vector if you can.
Full code:
#include <iostream>
bool noneZero(int *zero, int N) {
int PL = 0;
for (int i = 0; i < N; i++) {
if (*(zero + i) == 0) {
PL++;
}
}
if (PL == N)
return false;
else
return true;
}
int main(int argc, char** argv) {
int *z = new int[5]{0,0,0,0,0};
std::cout << noneZero(z,5);
delete[] z;
}

Why isn't my call to a value-returning function working? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I've tried to make sure my function prototype and definitions are good. The compiler doesn't show me any errors with those. And I've looked up in my textbook to make sure I'm writing my function call properly, but it still doesn't work. What am I missing? (VERY new to programming here. Please be kind.)
#include <iostream>
using namespace std;
bool noNegatives(int intArray[], int arraySize);
int main()
{
int mainArrSize = 5;
int mainArr[] = {7, 12, 4, 69, -2};
bool funcResult;
funcResult = noNegatives(mainArr, mainArrSize); //Here's the call that wont work
if (funcResult = true)
{
cout << "The array did not contain any negative"
<< " integers." << endl;
}
else
cout << "The array contained negative integers." << endl;
return 0;
}
bool noNegatives(int intArray[], int arraySize)
{
bool result = false;
int index;
for (index = 0; index < arraySize; index++)
{
cin >> intArray[index];
if (intArray[index] < 0)
return false;
}
return result;
}
Actually the compiler does warn about this line.
if (funcResult = true)
Perhaps you meant to compare
if (funcResult == true)
Always compile with at least -Wall, and take any warnings you see seriously. In fact, treat them like errors. You can even enforce this by compiling with -Werror.
1. Enable warnings and do not ignore them.
Here, the important part of the warning was "note: use '==' to turn this assignment into an equality comparison". (Note: this is the warning which Clang provides, other compilers will have different warning texts. All compilers will warn about this mistake.)
<source>:16:20: warning: using the result of an assignment as a condition without parentheses [-Wparentheses]
if (funcResult = true)
~~~~~~~~~~~^~~~~~
<source>:16:20: note: place parentheses around the assignment to silence this warning
if (funcResult = true)
^
( )
<source>:16:20: note: use '==' to turn this assignment into an equality comparison
if (funcResult = true)
^
==
1 warning generated.
2. Create and assign at the same time
This is your code:
bool funcResult;
funcResult = noNegatives(mainArr, mainArrSize); //Here's the call that wont work
if (funcResult = true)
I would declare and initialize the variable at the same time. I would write it like this:
bool funcResult = noNegatives(mainArr, mainArrSize); //Here's the call that wont work
if (funcResult = true)
Because if I do this, I can also make the variable const! And then, the little mistake would not compile, which would tell us about the problem earlier.
const bool funcResult = noNegatives(mainArr, mainArrSize); //Here's the call that wont work
if (funcResult = true) // Now this line won't compile anymore
3. Use C++ containers not C-style arrays
The (int intArray[], int arraySize) signature is dangerous (memory unsafe!) and can be replaced by either a std::vector<int> (if the size is not fixed at compile-time), or by std::array<int, 5> (if the size is known at compile-time).
Here's how your code would look like, after making this change:
#include <iostream>
#include <vector>
bool noNegatives(std::vector<int> const &intArray) {
bool result = false;
for (int index = 0; index < intArray.size(); index++) {
if (intArray[index] < 0)
return false;
}
return result;
}
int main() {
const std::vector<int> mainArr = {7, 12, 4, 69, -2};
const bool funcResult =
noNegatives(mainArr); // Here's the call that wont work
if (funcResult == true) {
std::cout << "The array did not contain any negative"
<< " integers.\n";
} else {
std::cout << "The array contained negative integers.\n";
}
return 0;
}
Minor changes there:
1. Do not use "using namespace std".
2. Moved the declaration and definition of noNegatives to the same place, just to make it a bit cleaner.
3. Do not use std::endl, prefer \n + std::flush. And in case the std::flush isn't needed, drop the flush.
4. If something is constant, just mark it as such. That's just a good habit. In this case, mainArr is constant.
4. Use modern C++ range-based for-loops
Instead of raw array access using indices, it is better to use a range-based loop. So we transform this code:
for (int index = 0; index < intArray.size(); index++) {
if (intArray[index] < 0)
return false;
}
into this:
for (int value: intArray) {
if (value < 0)
return false;
}
5. Optional: Use std::all_of
C++11 and later provides many great algorithms, so that you don't have to write your own. You are checking that a condition ("is Positive") holds for all elements in a container.
For this, std::all_of exists.
After including <algorithm>, we can make the noNegatives function be a single line:
bool noNegatives(std::vector<int> const &intArray) {
return std::all_of(array.begin(), array.end(), [](int x) { return x >= 0.; });
}
[](int x) { return x >= 0.; } is a lambda function and defines a function which takes an int x and then returns whether it is positive.
6. Optional: Get rid of iostreams
std::cout creates a lot of extra code when compiled. For fixed strings, you can use puts("Hello\n"); from #include <cstdio>. A more generic solution is to use fmt, but you'd have to install this on your system.
std::cout << "The array contained negative integers.\n"; becomes
puts("The array contained negative integers.\n");.
Final result:
https://godbolt.org/z/4FVyOw
#include <algorithm>
#include <array>
#include <vector>
#include <cstdio>
int main() {
const std::array<int, 5> mainArr {7, 12, 4, 69, -2};
const bool allPositive = std::all_of(mainArr.begin(), mainArr.end(), [](int x) { return x >= 0.; });
if (allPositive) {
puts("The array did not contain any negative integers.\n");
} else {
puts("The array contained negative integers.\n");
}
return 0;
}
Note, I replaced the vector<int> with std::array<int, 5> because then the compiler can optimize this to nothing. Here's the generated Assembly code:
main: # #main
push rax
mov edi, offset .L.str.1
call puts
xor eax, eax
pop rcx
ret
.L.str.1:
.asciz "The array contained negative integers.\n"

C++ There is a bool return type function returning (24) here

First of all sorry for too much code
Here there is a vector (teamNum) with type class, the class contain a vector (player) with type struct, it is a little complicated, but here in this function I need to check if there is a player in teamNum which contain tName equal to _tname (function parameter) contain (the player) pID equal to _pID (function parameter)
bool thereIsSimilarID(string _tname, int _pID)
{
for (int i = 0; i < teamNum.size(); i++)
{
if (teamNum[i].tName == _tname)
{
for (int j = 0; j < teamNum[i].player.size(); j++)
{
if (teamNum[i].player[j].pID == _pID)
return true;
}
}
else if (i == (teamNum.size() - 1))
{
return false;
}
}
}
And in the main
int main()
{
cout << "\n" << thereIsSimilarID("Leverpool", 1) << endl;
}
The output is 24 !!!!!
(good note that this happen just when the team (Leverpool) is the last team in the vector teamNum)
Again sorry for too much code but I need to know the bug not only fix the problem I need to learn from you
You encountered undefined behaviour.
If you take the if (teamNum[i].tName == _tname)-branch on the last element, but find no player with the correct pID, you don't return anything. Which means, that the return value is whatever random value is currently in the memory location that should hold the return value. In your case it happens to 24. But theoretically, everything could happen.
The same problem occurs when teamNum is empty.
The solution is to make sure to always return a value from a function (except if it has return type void of course):
bool thereIsSimilarID(string _tname, int _pID)
{
for (int i = 0; i < teamNum.size(); i++)
{
// In this loop return true if you find a matching element
}
// If no matching element was found we reach this point and make sure to return a value
return false;
}
You should take a look at your compiler settings and enable all the warnings. And often it's good to let it treat certain warnings as errors.

return statement in c++

What means
failing to provide a return after a loop that contains a return is an error
in "C++ primer fifth", page 295?
Especially, the compiler does not detect this error, what happens at run time is undefined.
I use the book sample like: (vs2013)
#include "stdafx.h"
#include "iostream"
#include "string"
using std::string;
bool str_subrange(const string &str1, const string&str2) {
if (str1.size() == str2.size())
return str1 == str2;
auto size = (str1.size() < str2.size()) ? str1.size() : str2.size();
for (decltype(size)i = 0; i != size; ++i) {
if (str1[i] != str2[i])
return false;
else
return true;
}
}
int _tmain(int argc, _TCHAR* argv[]) {
if (str_subrange("lyc", "talent"))
std::cout << "yes" << std::endl;
else
std::cout << "nope" << std::endl;;
system("pause");
return 0;
}
It works well, I want to know which situations that "return" is must.
If size is 0, the for loop never executes and so the method has no return value.
If size ends up as 0 (e.g. one of the strings is ""), your loop is never run. If the loop never runs, then what is returned is undefined, because the program won't write a result to be returned to the caller of the function. The result you get is whatever was preexisting in the memory contents of where the return value is expected on the stack.
When you decide to return values inside loops, or other grouping statements (e.g. "if"), always manually run your code in your head checking to ensure you return a value on every valid path and even if loops don't run.
In such case where using loops, if conditions, always return from end of function, assign a return value at start and update that value based on conditions.

C++ reading user inputs comparing array [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have this code where it read user code and store it on array, and later find sums of elements on each array and compare both of them, the code is as follows:
#include <iostream>
#include <vector>
#include <numeric>
typedef std::vector<int> int_vec_t;
//Call by reference to set variables in function
void readData(int_vec_t& v1, int_vec_t& v2)
{
v1 = int_vec_t{1,1,8}; //This only works for C++11
v2 = int_vec_t{2,2,2};
}
void readUserData(int_vec_t& v)
{
for(;;)
{
int val;
std::cin>>val;
if(val == 0) break;
v.push_back(val);
}
}
int main()
{
using namespace std;
int_vec_t A;
int_vec_t B;
readData(A,B);
//Or
readUserData(A);
readUserData(B);
int sumA = accumulate(A.begin(), A.end(), 0); //Then use iterators
int sumB = accumulate(B.begin(), B.end(), 0);
cout << ((sumA > sumB) ? "Array A Greater Than Array B\n" : "Array B Greater Than Array A\n");
return 0;
}
But the above code generate following errors:
test.cpp: In function ‘void readData(int_vec_t&, int_vec_t&)’:
I am using g++ test.cpp -o test to compile the code. What am I missing here?
don't you think the compilation should be something like:
$ g++ -std=c++11 test.cpp -o test ?
it keep taking inputs, how can i limit it to take only 5 elements per array
void readUserData(int_vec_t& v)
{
for(int i = 0; i < 5; i++)
{
int val;
std::cin>>val;
// if(val == 0) return;
v.push_back(val);
}
}
Great thanks, in between the loop how can out put statement so that user knows he is entering array for array 1 and after that array 2?
void readUserData(int_vec_t& v, std::string default = "")
{
for(int i = 0; i < 5; i++)
{
int val;
std::cout << "Enter for "<< default << "[" << i << "]: ";
std::cin>>val;
// if(val == 0) return;
v.push_back(val);
}
}
And from your main() you can send in a different string.
for example like this:
readUserData(A, "A");
readUserData(B, "B");
This was my code posted as a suggested solution to
c++ passing function into main error
Yes it needs a C++11 compiler as stated in the code. It was never meant as final code either.
I would recommend the OP to read a good book about C++. Let me suggest "C++ The Programming Language" http://www.amazon.com/The-Programming-Language-3rd-Edition/dp/0201889544