Calling function in C++ - c++

I'm trying to call a function with no return type but it doesn't seem to be getting called.
The code looks something like this(summarized):
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int ItemsInQuestion[4];
void GetQuestions(int NumQuests);
int main()
{
int NumberOfQuestions = 0;
srand((unsigned)time(NULL));
cout << "How many questions would you like?" << endl;
cin >> NumberOfQuestions;
cout << NumberOfQuestions << " questions will be asked.";
GetQuestions(NumberOfQuestions);
system ("PAUSE");
return 0;
}
void GetQuestions(int NumQuests)
{
for(int Questions=NumQuests; Questions>NumQuests; Questions++)
{
ItemsInQuestion[0]=(rand()%(263))+1;
ItemsInQuestion[1]=(rand()%(263))+1;
ItemsInQuestion[2]=(rand()%(263))+1;
ItemsInQuestion[3]=(rand()%(263))+1;
cout << ItemsInQuestion[0] << ' ' << ItemsInQuestion[1] << ' ' <<ItemsInQuestion[2] << ' ' << ItemsInQuestion[3];
}
}
The line that outputs the values in the array never comes up. What is causing this?

Because
int Questions=NumQuests;
and
Questions>NumQuests;
don't like each other.
You set Questions to NumQuests and then tell the loop to keep going as long as Questions is strictly greater than NumQuests, which it isn't to start off with.
Even if it was, you'd soon run into an overflow and undefined behavior.

This is not the way of using for-loops :
for ( __Initialization, __Condition, __Increment)
As Grigore pointed out in his answer, your initialization is wrong. As Questions=NumQuest, the statement Questions>NumQuests is false from the beginning, and your code is equivalent to
for ( ; 1<1 ; ) // I'm a lazy loop, I'm ugly and useless
There is an infinite number of way to do what you want :
// Direct : 0, 1, 2, .. NumQuest-1.
for (int Questions=0 ; Questions < NumQuests ; Questions++)
{ ... }
// Reverse : NumQuest, ..., 2, 1.
for (int Questions=NumQuests ; Questions > 0 ; Questions--)
{ ... }

Related

Mean and Mode of vector array - How can I make a smaller improvement in the function

Doing an exercise to find the mean and mode of a list of numbers input by a user. I have written the program and it works, but I'm wondering if my function 'calcMode' is too large for this program. I've just started looking into functions which is a first attempt. Would it be better to write smaller functions? and if so what parts can I split? Im pretty new to C++ and also looking if I can improve this code. Is there any changes I can make to make this run more efficient?
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int calcMean(vector<int> numberList)
{
int originNumber = numberList[0];
int nextNumber;
int count = 0;
int highestCount = 0;
int mean = 0;
for (unsigned int i = 0; i <= numberList.size() - 1; i++)
{
nextNumber = numberList[i];
if (nextNumber == originNumber)
count++;
else
{
cout << "The Number " << originNumber << " appears " << count << " times." << endl;
count = 1;
originNumber = nextNumber;
}
}
if (count > highestCount)
{
highestCount = count;
mean = originNumber;
}
cout << "The Number " << originNumber << " appears " << count << " times." << endl;
return mean;
}
int main()
{
vector<int> v;
int userNumber;
cout << "Please type a list of numbers so we can arrange them and find the mean: "<<endl;
while (cin >> userNumber) v.push_back(userNumber);
sort(v.begin(), v.end());
for (int x : v) cout << x << " | ";
cout << endl;
cout<<calcMean(v)<<" is the mean"<<endl;
return 0;
}
One thing to watch out for is copying vectors when you don't need to.
The function signature
int calcMode(vector<int> numberList)
means the numberList will get copied.
int calcMode(const & vector<int> numberList)
will avoid the copy. Scott Meyer's Effective C++ talks about this.
As an aside, calling is a numberList is misleading - it isn't a list.
There are a couple of points that are worth being aware of in the for loop:
for (unsigned int i = 0; i <= numberList.size()-1; i++)
First, this might calculate the size() every time. An optimiser might get rid of this for you, but some people will write
for (unsigned int i = 0, size=numberList.size(); i <= size-1; i++)
The size is found once this way, instead of potentially each time.
They might even change the i++ to ++i. There used to a potential overhead here, since the post-increment might involve an extra temporary value
One question - are you *sure this gives the right answer?
The comparison nextNumber == originNumber is looking at the first number to begin with.
Try it with 1, 2, 2.
One final point. If this is general purpose, what happens if the list is empty?
Would it be better to write smaller functions?
Yes, you can make do the same job using std::map<>; which could be
a much appropriate way to count the repetition of the array elements.
Secondly, it would be much safer to know, what is the size of the
array. Therefore I suggest the following:
std::cout << "Enter the size of the array: " << std::endl;
std::cin >> arraySize;
In the calcMode(), you can easily const reference, so that array
will not be copied to the function.
Here is the updated code with above mentioned manner which you can refer:
#include <iostream>
#include <algorithm>
#include <map>
int calcMode(const std::map<int,int>& Map)
{
int currentRepetition = 0;
int mode = 0;
for(const auto& number: Map)
{
std::cout << "The Number " << number.first << " appears " << number.second << " times." << std::endl;
if(currentRepetition < number.second )
{
mode = number.first; // the number
currentRepetition = number.second; // the repetition of the that number
}
}
return mode;
}
int main()
{
int arraySize;
int userNumber;
std::map<int,int> Map;
std::cout << "Enter the size of the array: " << std::endl;
std::cin >> arraySize;
std::cout << "Please type a list of numbers so we can arrange them and find the mean: " << std::endl;
while (arraySize--)
{
std::cin >> userNumber;
Map[userNumber]++;
}
std::cout << calcMode(Map)<<" is the mode" << std::endl;
return 0;
}
Update: After posting this answer, I have found that you have edited your function with mean instead of mode. I really didn't get it.
Regarding mean & mode: I recommend you to read more. Because in general, a data set can have multiple modes and only one mean.
I personally wouldn't split this code up in smaller blocks, only if i'd want to reuse some code in other methods. But just for this method it's more readable like this.
The order of excecution is aroun O(n) for calc which is quite oke if you ask me

C++: Why does my code stop running after the first for loop?

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT. */
string list[] = {"fiorello", "nonuterine", "asquint", "commodore", "semiprogressive",
"aviculturist", "brayley", "tendentious", "hungriness", "overbulkily",
"subfumigation", "praline", "fiorello", "presurvey", "unjealous",
"brayley", "unimpassionate", "welshman", "dcor", "traducianist"};
int size = sizeof(list);
for (int i = 0; i < size; i++) {
cout << list[i] << endl;
// THIS IS WHERE I REALIZE NOTHING ELSE PRINTS AFTER THIS POINT.
}
cout << endl;
int z = sizeof(list) / sizeof(list[0]);
sort(list, list + z);
for (int y = 0; y < z; y++) {
cout << list[y] << endl;
}
return 0;
}
I don't have a strong background in C++, coming from HTML, CSS etc. so trying to figure this out.
What I'm trying to accomplish is to print out the array, then print out in alphabetical order, then find duplicates and remove and print out again. And lastly, find length of each word in array and print that out.
As mentioned in comments, you are using sizeof incorrectly the first time. A good solution would be to not use it at all, instead use standard library algorithms which will find the size by template deduction:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
string list[]={"fiorello","nonuterine","asquint","commodore","semiprogressive","aviculturist","brayley","tendentious","hungriness","overbulkily","subfumigation","praline","fiorello","presurvey","unjealous","brayley","unimpassionate","welshman","dcor","traducianist"};
// Operate on each item in list - don't need to mention count explicitly
for ( auto&& s : list )
cout << s << '\n';
cout << endl;
// Same as sort(list, list+z)
sort( begin(list), end(list) );
for ( auto&& s : list )
cout << s << '\n';
cout << endl;
}
Your comments suggest you plan to remove duplicates but you still want to use a C-style array. So presumably you'll be using a variable for the list count; you can get this by using:
size_t count = distance( begin(list), end(list) );
rather than using the sizeof thing. As well as being less error-prone, this will keep working even if you later change the code to use a container instead of a C-style array.

A c++ program that stores the positions of each bit 1 in a binary sequence

I have made this code to store the position of each bit 1 entered in a binary sequence. The output of the program is not what it is desired. The output I get for 10100 is 0x7fff9109be00. Here is the code:
#include <iostream>
#include <bitset>
using namespace std;
int main()
{
bitset <5> inpSeq;
int x = 0;
int xorArray[x];
unsigned int i;
cout << "Enter a 5-bit sequence: \n";
cin >> inpSeq;
for ( i = 0; i < inpSeq.size(); i++)
{
if ( inpSeq[i] == 1 )
{
x = x+1;
xorArray[x] = i;
}
}
cout << xorArray << "\n";
}
Update for clarity: What I had in mind was that 'cout << xorArray' will print bit 1's positions.
cout << xorArray << "\n";
This does not print the elements of xorArray; it prints its address.
You must iterate ("loop over") it:
for (auto x : xorArray)
cout << x << ' ';
cout << '\n';
Your other problem is that you're trying to use a variable-length array, which does not exist in C++. Use a vector instead.
Now it gives you your desired output:
#include <iostream>
#include <bitset>
#include <vector>
using namespace std;
int main()
{
bitset<5> inpSeq("10111");
std::vector<int> xorArray;
for (unsigned int i = 0; i < inpSeq.size(); i++) {
if (inpSeq[i] == 1)
xorArray.push_back(i);
}
for (auto x : xorArray)
cout << x << ' ';
cout << '\n';
}
If you're not using C++11 for whatever reason, you can perform that final loop the traditional way:
for (std::vector<int>::const_iterator it = xorArray.begin(),
end = xorArray.end(),
it != end; ++it) {
cout << *it << ' ';
}
Or the naive way:
for (unsigned int i = 0; i < xorArray.size(); i++)
cout << xorArray[i] << ' ';
I am a little unclear on exactly what you are trying to achieve, but I think the following might help.
#include <iostream>
#include <bitset>
#include <list>
using namespace std;
int main() {
bitset<5> inpSeq;
unsigned int i;
list<int> xorList;
cout << "Enter a 5-bit sequence: \n";
cin >> inpSeq;
for (i = 0; i < inpSeq.size(); ++i) {
if (inpSeq[i] == 1) {
xorList.push_back(i);
}
}
for (list<int>::iterator list_iter = xorList.begin();
list_iter != xorList.end(); list_iter++)
{
cout << *list_iter << endl;
}
return 0;
}
The reason why I am using a list is because you mentioned wanting to store the positions of the 1 bit. The list is being used as the container for those positions, in case you need them in another point in the program.
One of the problems with the original code was that you assigned variable 'x' the value 0. When you declared xorArray[x], that meant you were essentially creating an array of length 0. This is incorrect syntax. It looks like you actually were trying to dynamically allocate the size of the array at runtime. That requires a different syntax and usage of pointers. The list allows you to grow the data structure for each 1 bit that you encounter.
Also, you cannot print an array's values by using
cout << xorArray << endl
That will print the memory address of the first element in the array, so, xorArray[0]. Whenever you want to print the values of a data structure such as a list or array, you need to iterate across the structure and print the values one by one. That is the purpose of the second for() loop in the above code.
Lastly, the values stored are in accordance with the 0 index. If you want positions that start with 1, you'll have to use
xorList.push_back(i+1);
Hope this helps!

Formatting C++ output problem

Let me examplify my problem , I've a function like:
void printer(int width, int hight){
for(int i=0;i<width;++i) std::cout<<" & ";
for(int i=0;i<hight;++i) std::cout<<" ^ ";
std::cout<<std::endl;
}
my problem is function printer should always output of both for loop in same width
e.g:
output could look (width 5):
&^
&&&^
or there is anyway that i print any of (from above code) for loop's output in constant width independent of no of times for loop executes
Question is unclear. Are you looking for something like the following ?
void printer(int amps, int carets, int overallWidth){
for (int i = amps + carets; i < overallWidth; i++) std::cout<<" "; // leading padding
for (int i=0;i<amps;++i) std::cout<<"&";
for (int i=0;i<carets;++i) std::cout<<"^";
std::cout<<std::endl;
}
The change was just to add a loop for outputting the padding. (also changed the parameters name for clarity)
printer(1,1,5);
printer(3,1,5);
would then produce the output shown in example
&^
&&&^
and of course, rather than being passed as a parameter, the overallWidth variable could be hardcoded; an implicit constant of the printer() function.
Edit:
The snippet above stayed very close to that of the question. There are however more idiomatic approaches, for example the following "one liner", which uses one of the string constructor overloads to produce the strings of repeated characters, and iomanip's setw() to produce the padding.
void printer(int amps, int carets, int overallWidth){
std::cout << setiosflags(ios::right) << setw(overalWidth)
<< string(amps, '&') + string (carets, '^')
<< std::endl;
}
Look into <iomanip>. Using cout you can specify a width.
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
cout << setiosflags(ios::left) << setw(10) << "Hello"
<< setiosflags(ios::right) << setw(20) << "World!";
return 0;
}

Unknown crash in a C++ Memory Pointers Exercise

I recently wrote a program to help me understand the basics of memory pointers in C++, I chose a simple prime number finder.
I finally got it to work. (yay for debugging!)
And I let it run to see how far it goes, it gets to prime #815389 with my verbose tells me is the 65076th prime, I get an app crash. The one thing I could think of was my ints overflowing so I changed them to longs, it gets stuck at the same place.
Would someone be able to help explain what limitation is causing this?
comp: WinVista 64-bit Home Premium, 6GB ram AMD 4800+ X2
program crashes at 4,664K memory usage
Source:
#include <cstdlib>
#include <iostream>
\\\\(Backslashes added for readability)
using namespace std;
long number;
long numnum;
class num;
class num {
public:
long i;
void check();
bool nxt;
num* nxtnum;
};
void num::check() {
if (number % i != 0) {
if (nxt == true) {
(*nxtnum).check();
} else {
nxtnum = new num();
(*nxtnum).i = number;
numnum++;
cout << numnum << ":" << number << ", ";
nxt = true;
};
};
};
int main(long argc, char *argv[]){
numnum = 1;
cout << numnum << ":" << 2 << ", ";
num two;
two.i = 2;
for (number = 3; 1<=1000001; number++) {
two.check();
};
cout << endl;
system("PAUSE");
return EXIT_SUCCESS;
};
(Nevermind the username it's just an alias I use so I can keep track of all my posts with google)
Stack overflow? I see that check is recursive.
I'd put a guess on the fact that two.nxt isn't initialized. In C, primitive datatypes aren't initialized, meaning they have the value of whatever happened to be in whatever memory it's now occupying. That means that more than likely, in main(), two.nxt = true, which causes check() to be run on an invalid pointer. Try explicitly setting it to false and see if that works for you.
[edit] If this is the issue, the more important initialization would be when you allocate the new num in check().
Sean is right, two.nxt is never initialised. In fact, num.nxt is never initialised for any instance of num. The member nxt is unnecessary if the class is made more robust. The nxt pointer can be used instead:
class num
{
private:
long i;
num *nxtnum;
public:
num (long value) : i (value), nxtnum (0) { }
void check ()
{
if (number % i != 0)
{
if (nxtnum)
{
nxtnum->check ();
}
else
{
nxtnum = new num (number);
cout << ++numnum << ":" << number << ", ";
}
}
};
Of course, the recursive nature is probably the main culprit, the initialisation issue was hidden as you were probably running a debug build. Converting the recursive form to the iterative form is left as an exercise.
Couple of problems I can see:
You're allocating a bunch of nums, but you're not checking for a std::bad_alloc exception. You might simply be running out of memory...
You're not checking anywhere if nxtnum is != 0, even though I think it's safe to do so as the only places where you dereference it are guarding. Nevertheless, it's not that great a practise.
As Sean Edwards mentions, the num class doesn't have a constructor, so the members of a newly created num are filled with pretty much random junk. And that random junk might include nxt being set to a nonzero value. I'd add the following constructor to give it a set of safe defaults:
num::num() : i(0), nxt(false), nxtnum(0) {}
You don't really need the boolean value, I'd just check for nxtnum being non-zero.
As Jeff Yates says, you might suffer from a stack overflow as the recursive function is getting nested too deep, but it doesn't look like it'll recurse that deep.
Incidentally, if you're using a Microsoft compiler, int and long are the same size when targeting x64. You also have an infinite loop in your main function, as 1 will always be <= 1000001.
I've got it working, thank you Skizz
#include <cstdlib>
#include <iostream>
#include <windows.h>
using namespace std;
long number;
long numnum;
class num;
num *two;
num *nn;
num *bre;
class num
{
private:
long i;
num *nxtnum;
public:
num (long value) : i (value), nxtnum (0) { }
void *check ()
{
if (number % i != 0)
{
if (nxtnum)
{
//nxtnum->check ();
nn = nxtnum;
}
else
{
nxtnum = new num(number);
cout << ++numnum << ":" << number << ", ";
nn = bre;
}
}else{nn=bre;}
}
};
int main(long argc, char *argv[])
{
numnum = 1;
cout << numnum << ":" << 2 << ", ";
two = new num(2);
nn=two;
for (number = 3; 1<=1000001; number++) {
while (nn!=bre){
nn->check();
Sleep(0);
}
nn=two;
};
cout << endl;
system("PAUSE");
return EXIT_SUCCESS;
};
For Those Interested