Error when passing function as an argument in C++ [closed] - c++

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 6 years ago.
Improve this question
I encountered this strange thing with with C++ when i tried to pass a function as an argument to another one. the problem here is that it works but not giving me the expected result.
here's my code (msvc2013):
#include <stdio.h> /* printf, NULL */
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */
#include <iostream>
typedef unsigned int uint32_t;
typedef unsigned char uint8_t;
using namespace std;
#include "stdafx.h"
uint32_t random_color()
{
uint8_t r = rand() % 255;
uint8_t g = rand() % 255;
uint8_t b = rand() % 255;
uint32_t rgb = ((uint32_t)r << 16 | (uint32_t)g << 8 | (uint32_t)b);
return rgb;
}
void print_rgb(uint32_t(*color_generator)() = &random_color)
{
std::cout << color_generator << std::endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
for (int i = 0; i < 5; i++)
{
srand(time(NULL));
print_rgb();
}
system("PAUSE");
return 0;
}
the purpose of this code is more complicated, but this is a minimal example.
Question : although as you see, there was an srand(time(NULL)); in order for rand() to change values, it dosen't !
so , at the 5 times, I got the same value !
Is there any reason for this ? Am I missing something ?

looks like you are printing value of pointer to function, your code should be:
std::cout << color_generator() << std::endl;

Nothing weird is going on. This code prints out the address passed into it, and the address isn't random.
void print_rgb(uint32_t(*color_generator)() = &random_color)
{
std::cout << color_generator << std::endl;
}
You either need to call the function, here or, if your intention was that appending it to the stream would call it, instead implement something similar to a stream manipulator.

Related

I get a warning when I try to run the recursion program with return keyword [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 9 months ago.
The community reviewed whether to reopen this question 9 months ago and left it closed:
Original close reason(s) were not resolved
Improve this question
I was expecting 1 2 3 as output, but when I try to run this code:
#include <iostream>
using namespace std;
int fun(int x){
if (x>0){
return fun(x-1);
cout<<x<<endl;
}
}
int main()
{
int x=3;
fun(x);
return 0;
}
I get this warning:
warning: control reaches end of non-void function
Why doesn't it return the value and call fun(x-1)?
But the below code works perfectly. I get 3 2 1 as output.
#include <iostream>
using namespace std;
int fun(int x){
if (x>0){
cout<<x<<endl;
return fun(x-1);
}
}
int main()
{
int x=3;
fun(x);
return 0;
}
Once a function has return'ed, it can't execute any more code:
if (x>0){
return fun(x-1);
cout<<x<<endl; // <-- NEVER EXECUTED
}
The warning is because your function has a non-void return type, but is not return'ing any value when x is <= 0, thus causing undefined behavior.
Try this instead:
#include <iostream>
using namespace std;
int fun(int x){
if (x>0){
int ret = fun(x-1);
cout << x << endl;
return ret;
}
return 0;
}
int main()
{
fun(3);
return 0;
}
Online Demo

Random string from vector C++ [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 1 year ago.
Improve this question
I have a question about this code. I got what I was expecting but I don't understand why sometimes I get the result and sometimes not.
In this case, the output suppose to show the word "dive" every time I run the code but sometimes the output is not giving me any value.
Is it because the if statement? How can I get always the result("dive") and not sometimes?
#include <iostream>
#include <string>
#include <vector>
#include <ctime>
using namespace std;
int main()
{
srand(time(NULL));
vector <string> Words = {"dive", "friends", "laptop"};
string n_words = Words[rand() % Words.size()];
for(int i = 0; i < 1; i++)
{
if(n_words.length() <= 4)
{
cout << n_words << endl;
}
}
}
EDIT ANOTHER EXAMPLE:
I would like to pick up a random word not longer than 4 letters from a list of words with differents lengths. When I run my code sometimes I get "dive" sometimes "lego" and sometimes nothing. Is there any way to get always some of this two values ?
#include <iostream>
#include <string>
#include <vector>
#include <ctime>
using namespace std;
int main()
{
srand(time(NULL));
vector <string> Words = {"dive", "table", "laptop", "lego", "friends"}
string n_words = Words[rand() % Words.size()];
for(int i = 0; i < 1; i++)
{
if(n_words.length() <= 4)
{
cout << n_words << endl;
}
}
}
Personally I would copy to a secondary temporary vector, shuffle it, and get the first element of that vector.
And I would have put it in a separate function.
In code something like this perhaps:
std::string select_random_short_word(std::vector<std::string> const& long_words)
{
// Create a vector and copy all "short" words to it
std::vector<std::string> short_words;
std::copy_if(begin(long_words), end(long_words), std::back_inserter(short_words),
[](std::string const& w) { return w.length() <= 4; });
// Make sure there are any short words
if (short_words.size() == 0)
{
return ""; // Nope, no short words
}
// Randomly shuffle the short words
std::random_device device;
std::default_random_engine engine(device());
std::shuffle(begin(short_words), end(short_words), engine);
// Return a random short word
return short_words[0];
}
This will reduce your main function to simply:
int main()
{
std::vector<std::string> words = {"dive", "table", "laptop", "lego", "friends"};
std::cout << select_random_short_word(words) << '\n';
}

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;
}

Any idea why this user defined literals fails? [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 4 years ago.
Improve this question
I have the following code which implements the adler32 checksum:
constexpr uint32_t adler32(std::string_view sv)
{
constexpr const uint32_t MOD_ADLER= 65521;
uint32_t rv= 0, a= 1, b= 0;
for (unsigned char c:sv)
{
a= (a+c)%MOD_ADLER;
b= (b+a)%MOD_ADLER;
}
rv= a|(b<<16);
return rv;
}
//----------------------------------------------------
constexpr uint16_t operator ""_csum(const char* str,long unsigned len)
{
return adler32(std::string_view(str,len));
}
and the following test routine:
#include "adler32.h"
using easyUtils::operator""_csum;
#include <iostream>
using namespace std;
int main()
{
auto i= easyUtils::adler32("hello");
auto j= "hello"_csum;
auto k= easyUtils::adler32("hello");
cout << i << '\t' << j << '\t' << k << endl;
return 0;
}
Which gives the following output when compiled for std=c++17 using either clang or g++ under Linux:
./test/adlerTest
103547413 533 103547413
I would have expected 103547413 three times. Any ideas why this is not so?
constexpr uint16_t operator ""_csum
^^
And
103547413L % 65536L == 533L

C++: invalid use of 'void' [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 6 years ago.
Improve this question
This code should print i = 35 as result but somehow it doesn't even compile. Why ?
#include <iostream>
using namespace std;
void increment(int &p){
p = p +10;
}
int main()
{
int i = 10;
increment(i) += 15;
cout<<"i = " <<i<<endl;
return 0;
}
No it shouldn't! increment has void as return type, that means that an expression call to this function has no value. If you want that call to be able to be used on the left part of an assignment, it must return a left-value.
Basically, when you write a=b a denotes a container but b a value.
You can try:
int &increment(int &p){
p = p +10;
return p; // return the reference passed as argument...
}
int main()
{
int i = 10;
increment(i) += 15;
cout<<"i = " <<i<<endl;
return 0;
}