I'm a beginner in C++ so please bear with me. Below is just a part of the full program.
When the user inputs the first number (assume '3'), it goes to the if statement.
a[count ++] then becomes a[1] (if I'm not wrong, because count is initially 0). The array element a[1] thus stores the input which is 3. If so, then didn't the program just skip a[0]?
int readarray(int a[], int capacity) {
int count = 0;
int input;
do {
cout << "Enter a number (-1 to stop): ";
cin >> input;
if (input != -1) {
a[count++] = input;
}
} while (input != -1 && count << capacity);
return count;
Because count++ is a post increment operator. It uses the current value of count in the expression and also increments count. It's not defined how or when the increment happens so any other uses of count in the same statement could have unexpected results.
The statement is equivalent to writing
a[count] = input;
count = count + 1;
As a matter of personal opinion I think you should never use the pre/post increment/decrement operators in an expression. It doesn't produce any more efficient code, it is rather less readable and tends to end up with off by one errors.
No, postfix increment (x++) returns the old value of the variable. So a[count++] increments count from 0 to 1, but uses 0 (the old value of count) as the index.
By the way, count << capacity looks wrong. Did you mean count < capacity?
Instead of a[count++] you can do if(input != -1){a[count] = input; count++}. In this way the value will be assigned to current array index say at start, it will be assigned to a[0] and then count will be incremented to 1. So next iteration will have a[1].
Related
#include<iostream>
using namespace std;
int main(){
int i = 1;
int sum;
int N;
cout << "Enter a number N: ";
cin >> N;
while(i<=N)
{
if(i%2 == 0)
{
sum = sum + i;
}
else
{
i = i + 1;
}
}
cout << sum;
}
This is to print the sum of all even numbers till 1 to N.
As I try to run the code, I am being asked the value of N but nothing is being printed ahead.
For starters the variable sum is not initialized.
Secondly you need to increase the variable i also when it is an even number. So the loop should look at least like
while(i<=N)
{
if(i%2 == 0)
{
sum = sum + i;
}
i = i + 1;
}
In general it is always better to declare variables in minimum scopes where they are used.
So instead of the while loop it is better to use a for loop as for example
for ( int i = 1; i++ < N; ++i )
{
if ( i % 2 == 0 ) sum += i;
}
while(i<=N)
{
if(i%2 == 0)
{
sum = sum + i;
}
else
{
i = i + 1;
}
}
Let's step through this. Imagine we're on the loop where i = 2 and you've entered N = 5. In that case...
while(i <= N)
2 <= 5 is true, so we loop
if(i%2 == 0)
2 % 2 == 0 is true, so we enter this branch
sum = sum + i;
Update sum, then head back to the top of the loop
while(i <= N)
Neither i nor N have changed, so 2 <= 5 is still true. We still loop
if(i%2 == 0)
2 % 2 == 0 is still true, so we enter this branch again...
Do you see what's happening here? Since neither i nor N are updated, you'll continue entering the same branch and looping indefinitely. Can you think of a way to prevent this? What would need to change?
Also note that int sum; means that sum will have a garbage value (it's uninitialized). If you want it to start at 0, you'll need to change that to
int sum = 0;
You're looping infinitly when i is even because you don't increase it.
Better option would be this if you want to use that while loop :
while(i<=N)
{
if(i%2 == 0)
sum = sum + i;
i=i+1;
}
cout << sum;
If you don't need to do anything when the condition is false, just don't use an else.
No loops are necessary and sum can be evaluated at compile time if needed too
// use unsigned, the whole excercise is pointless for negative numbers
// use const parameter, is not intended to be changed
// constexpr is not needed, but allows for compile time evaluation (constexpr all the things)
// return type can be automatically deduced
constexpr auto sum_of_even_numbers_smaller_then(const unsigned int n)
{
unsigned int m = (n / 2);
return m * (m + 1);
}
int main()
{
// compile time checking of the function
static_assert(sum_of_even_numbers_smaller_then(0) == 0);
static_assert(sum_of_even_numbers_smaller_then(1) == 0);
static_assert(sum_of_even_numbers_smaller_then(2) == 2);
static_assert(sum_of_even_numbers_smaller_then(3) == 2);
static_assert(sum_of_even_numbers_smaller_then(7) == 12);
static_assert(sum_of_even_numbers_smaller_then(8) == 20);
return 0;
}
int main(){
int input; //stores the user entered number
int sum=0; //stroes the sum of all even numbers
repeat:
cout<<"Please enter any integer bigger than one: ";
cin>>input;
if(input<1) //this check the number to be bigger than one means must be positive integer.
goto repeat; // if the user enter the number less than one it is repeating the entry.
for(int i=input; i>0; i--){ // find all even number from your number till one and than totals it.
if(i%2==0){
sum=sum+i;
int j=0;
j=j+1;
cout<<"Number is: "<<i<<endl;
}
}
cout<<endl<<"The sum of all even numbers is: "<<sum<<endl;}
Copy this C++ code and run it, it will solve your problem.
There are 2 problems with your program.
Mistake 1
The variable sum has not been initialized. This means that it has(holds) an indeterminate value. And using this uninitialized variable like you did when you wrote sum = sum + i; is undefined behavior.
Undefined behavior means anything1 can happen including but not limited to the program giving your expected output. But never rely on the output of a program that has undefined behavior.
This is why it is advised that:
always initialize built in types in local/block scope.
Mistake 2
The second problem is that you're not updating the value of variable i.
Solution
You can solve these problems as shown below:
int main(){
int i = 1;
int sum = 0; //INITIALIZE variable sum to 0
int N;
cout << "Enter a number N: ";
cin >> N;
while(i<=N)
{
if(i%2 == 0)
{
sum = sum + i;
}
i = i + 1; //update(increase i)
}
cout << sum;
}
1For more reading(technical definition of) on undefined behavior you can refer to undefined behavior's documentation which mentions that: there are no restrictions on the behavior of the program.
For clarification, let's consider the following program:
#include <iostream>
int main(void) {
short int i; // declaration
short int value;
short int sum;
i = value = sum = 0; // initialization
std::cout << "Enter a value: ";
std::cin >> value;
while (i != value) { // ### here's the confusion ###
sum += i;
i++;
}
std::cout << "Total sum: " << sum << std::endl;
return 0;
}
Look at the while (i != value), when this expression is given, the results shows Total sum: 45 whereas if we put while (i <= value), it shows Total sum: 55. (Input's given 10 for example)
Here, the confusion is, when should we use != and <= or >= operations in loops, any specific condition?
According to TutorialsPoint's Operators Reference
it tells that != (returns true used when two operands are unequal).
<= (returns true when used when we need to ensure if the first operand is lesser than or equal to second).
It was expected to get no difference in output, but something's misunderstood.
This while loop
while (i != value)
does not include the iteration when i is equal to value because in this case the condition i != value evaluates to false.
This while loop
while (i <= value)
includes the iteration when i is equal to value because in this case the condition i <= value evaluates to true.
In fact the first condition can be rewritten the following way (provided that initially i is less than value)
while ( i < value )
Now compare it with the condition in the second loop that in turn can be rewritten like
while ( i < value || i == value )
That is you have two different conditions.
With
while( i <= value)
the last iteration is with i == value. With
while ( i != value)
The body of the loop will not be executed when i == value. That is the reason you observe the difference.
This is a good chance to learn how to use a debugger. And/Or realize that your example is already too complicated to directly see what is going on. You would have spotted the difference more easily with
int i = 0;
int value = 5;
while ( i != value) {
std::cout << i << " ";
}
i = 0;
while ( i <= value) {
std::cout << i << " ";
}
#include <iostream>
using namespace std;
int main()
{
int count;
int range;
cout << "Enter the range of two numbers" << endl;
cin >> range;
for (count = 0; count <= range; count++)
{
count = count + 1;
cout << count << endl;
}
system("pause")
return 0;
}
the output displays:
Enter the range of two numbers
9
1
3
5
7
9
Press any key to continue...
count is incremented twice in each loop. Once in the loop iterator (the "for" line) and once where you set count = count +1;
First time round the for loop, count = 0, then it’s incremented (1), then printed. Then incremented in the "for" line (2), incremented by count = count +1 (3) then printed.
When you increment count in the for loop your incrementing the variable "count" not just the for loop itself.
In c++, a for loop that increments by one can also be written as:
int count = 0;
for(;count <= range;;){
//code here
count++;
}
So the code you have written actually increments the for loop like this:
int count = 0;
for(; count <= range;;){
//code here
count = count + 1;
count++;
}
Which adds 1 twice to count, which is the same as adding 2.
Thus, your loop skips over every other number giving you odd outputs.
You are modifying count in your loop (count++) as well as in the body of the loop count = count + 1; so of course it increases by 2 each iteration.
What did you expect?
C++ Code:
#include<iostream>
using namespace std;
int main()
{
int N;
cin>>N;
int *A = new int[N];
int i=0;
for(i=0;i<N;i++)
cin>>A[i];
while(cout<<A[--N]<<' ' and N);
delete[] A;
return 0;
}
Print the integers of the array in the reverse order in a single line separated by a space.
Does anyone know what is "and N" do in cout statement?
It's a cryptic way of writing:
while( (cout<<A[--N]<<' ') and (N != 0) );
// output is successful and N is not equal to zero.
It could be written more clearly as:
for ( ; N != 0; --N)
{
cout << A[N-1] << ' ';
}
Since it's theoretically possible for N to be negative, it will be better to use:
for ( ; N > 0; --N)
{
cout << A[N-1] << ' ';
}
N is an integer variable, value of type int can be implicitly converted to bool (non zero becomes true and zero becomes false). So the expression basically sais execute when result of operator<< converted to bool is true and N is not equal to zero. Logically this code
while(cout<<A[--N]<<' ' and N);
is equal to:
do {
bool b1 = cout<<A[--N]<<' ';
bool b2 = N;
} while( b1 and b2 );
actual code is a little different due to short circuit but that differences are unimportant in this case.
The part and N that can be also written like && N of the while statement
while(cout<<A[--N]<<' ' and N);
that as it has been pointed out can be rewritten like
while(cout<<A[--N]<<' ' && N != 0);
checks that N that is being decreased (A[--N]) in each iteration of the loop is not equal to 0.
So the loop outputs elements okf the array in the reverse order.
The word and is a so-called alternative token for the primary token &&.
It is just a way of writing the code by some programmers.
It is actually written as
while( (cout<<A[--N]<<' ') and (N != 0) );
Basically 'and' operator returns true when both operands are non zero values.
So cout will give number of characters it printed which will be non zero in this case and until the value of N becomes zero your loop will be execute.
I'm C++ begginer. I did this excercise from Deitel's book:
Use a one-dimensional array to solve
the following problem. Read in 20
numbers, each of which is between 10
and 100, inclusive. As each number is
read, validate it and store it in the
array only if it is not a duplicate of
a number already read. After reading
all the values, display only the
unique values that the user entered.
Provide for the "worst case" in which
all 20 numbers are different. Use the
smallest possible array to solve this
problem.
Here is my code:
#include <iostream>
using namespace std;
bool compare(int arrayNum[],int arraySize,int element);
int main()
{
const int size=20;
int i=1;
int num[size];
int arrayElement;
int counter=0;
while(i<=20)
{
cin>>arrayElement;
if(i==1) //stores first element in array
num[0]=arrayElement;
//compare new element with stored elements
//if element is not a duplicate store it in array
else if (compare(num,size,arrayElement))
{
counter++;
num[counter]=arrayElement;
}
i++;
}
//displays array elements
for(int k=0;k<=counter;k++)
cout<<num[k]<<endl;
return 0;
}
//compare elements in array
bool compare(int arrayNum[],int arraySize,int element)
{
for(int j=0;j<arraySize;j++)
{
if(arrayNum[j]==element)
return false;
}
return true;
}
It works, but I'm not sure if I have interpreted the task correctly. I assume then I don't have to include conditional statement for range of numbers (10 to 100 inclusive), as this will be read from the keyboard and input by me. Therefore why was this instruction included? Also at the end it says
use the smallest possible array
I assume the max size has to be 20,but I don't think there is a way to dynamically expand array size (for example while storing new elements) as array size is const. I would appreciate if someone could help me with this. Any comments regarding code, or better solution are welcome.
As each number is read, validate
it and store it in the array
Emphasis mine. The text clearly says that your program has to validate the input. In other words, it has to check that the entered number is between 10 and 100, and if it is not, handle the error appropriately. So yes, you do need a conditional, although exactly what you do to handle the error is up to you.
And you're right, since arrays aren't dynamically resizable, the array size has to be at least 20.
You do need a conditional. Basically it's saying to take in a number between 10 and 100. If it's not a number between those ranges, don't store it. Also, if that number already exists in the array, don't store it. Then just print out the values in the array.
You assume correct about the array size, it's maximum size would be 20, although you may not store all 20 values (again, because some input might be bad).
The smallest possible array is a char[12], where the individual bits are used as flags.
char data[12]; // memset(data, 0, sizeof(data)); in main();
void set(int n_raw;)
{
int n = n_raw - 10;
int index = n/8;
int offset = n-8*index;
data[index] |= 1 << offset; // added "1 <<"
}
Reading the values back is left as an exercise for the student.
I assume then I don't have to include
conditional statement for range of
numbers (10 to 100 inclusive), as this
will be read from the keyboard and
input by me. Therefore why was this
instruction included?
Sure, in this case you wrote the code and know to enter numbers within the range expected; however, it is a standard best-practice to always validate input data from a user, always. That way erroneous values are handled gracefully (with an appropriate error message) and helps to make your program more robust.
Also at the end it says
use the smallest possible array
I assume the max size has to be 20,,,
I think what they might have been getting at here is that you could have used an array of 91 bytes as shown below.
int cnt = 0; // count of unique values entered
byte values[91]; // values entered indicator array
int valIdx; // used as values array index
memset((void *)values, 0, sizeof(values)); // initialize array to all zeros
while ( cnt < 20 )
{
// [code for the following comments not shown]
// have user input a number
// validate the number (>= 10 && <= 100)
// subtract 10 from the number and store it in valIdx
// (now valIdx will contain a number >= 0 <= 90)
if ( !values[valIdx] )
{
values[valIdx] = 1;
++cnt;
}
}
// then to show the unique values...
for ( valIdx = 0; valIdx < sizeof(values); valIdx++ )
{
if ( values[valIdx] )
{
cout << valIdx + 10 << endl;
}
}
That solution however, would not have met the "use the smallest array possible" requirement.
Back to your code...
I would go ahead and add the user input validation, just for completeness (and to get into the habit of never trusting users (especially yourself).
As far as improvements go, here is one thing to think about. The compare routine goes through every array element when a unique number has been entered. It only needs to check against those that have a stored value in them. Making that change should lead you to refactor the contents of your while loop as well.
I'm studying C++ in the same book!!
My first implementation for solving this problem was one that don't use any complementar array.. it uses a linear search to find duplicates..
take a look:
#include <iostream>
using namespace std;
// remember: size_t = unsigned int
const size_t arraySize = 20;
size_t _array[ arraySize ];
// global variable to keep track of the last used
// position in the _array
size_t counter = 0;
// the argument is not changed, so pass it by
// const reference
bool dupSearch( const int & );
int main()
{
// disregard this
ios_base::sync_with_stdio( false );
// "temp" variable declared outside the loop to
// avoid repeated allocation and deallocation
int i = arraySize, temp;
// look at the loop condition below " ( i-- ) "
// remember:
// false = ( every expression evaluated to 0 )
// true = ( every expression evaluated to a non-zero result )
// more details on pag. 108 of the book. 8/e Portability tip 4.1
while ( i-- )
{
// read the number from the user
cin >> temp;
// if the number entered is valid, put the
// number on _array[ counter ] and increment 'counter'
if ( dupSearch( temp ))
{
_array[ counter ] = temp;
++counter;
}
}
// print the result in column format
cout << endl;
for ( size_t j = 0; j < counter; ++j )
cout << _array[ j ] << endl;
}
// validation: if the value is out of the described range, return false
// if is in the range, check for duplicates using linear search.
// if a duplicate is found, return false
// otherwise, return true.
bool dupSearch( const int &a )
{
if ( a < 10 || a > 100 )
return false;
else
for ( size_t i = 0; i < counter; ++i )
if ( _array[ i ] == a )
return false;
return true;
}
the number of comparisons is
n = ( n * ( n + 1 )) / 2
where n = counter. worst case --> counter = 20 numbers --> loop 210 times through the program execution.