i'm trying to create a program which checks if input is is an int or a string.
This is the code:
// CPP program to check if a given string
// is a valid integer
#include <iostream>
using namespace std;
// Returns true if s is a number else false
bool isNumber(string s)
{
for (int i = 0; i < s.length(); i++)
if (isdigit(s[i]) == false)
return false;
return true;
}
// Driver code
int main()
{
// Saving the input in a string
string str = "6790";
// Function returns 1 if all elements
// are in range '0-9'
if (isNumber(str))
cout << "Integer";
// Function returns 0 if the input is
// not an integer
else
cout << "String";
}
I wanted to ask that whether i++ or ++i is better for this loop and why?
for (int i = 0; i < s.length(); i++)
if (isdigit(s[i]) == false)
return false;
THANK YOU!
I prefer the form ++i in C++, because i may be an iterator or other object with overloaded operator++. In those cases, the form i++ generates a temporary object to hold the previous value of i, while the form ++i does not. The compiler may optimize away that temporary object, but it’s not required to, and in some cases may not be allowed to.
So, ++i is slightly better than i++ as the former need not retain the initial value and recheck it. It is one of the very few instances where time optimization and memory optimization occur simultaneously. But the difference is too small to be noted, just 4 bytes. Also, the time difference is negligibly small.
You would essentially get the same answer in your example but might receive a minute time and memory optimization while using ++i.
Since the datatype of i is int, it doesn't matter if you use i++ or ++i.
If its a large class iterator, ++i is faster than i++. Its a good practice to use ++i.
Related
I am trying to reverse iterate through a string, but am getting assertion failure for the [] operator in the latest VS.
int foo() {
std::string s = "s";
for (int i = (s.size() - 1); i >= 0; i--) {
std::cout << s[i] << std::endl;
}
return 0;
}
Commenting out the cout line gives infinite loop warning and indeed enters infinite loop:
int foo2() {
std::string s = "s";
for (int i = (s.size() - 1); i >= 0; i--) {
//std::cout << s[i] << std::endl;
}
return 0;
}
Iterating forwards works just fine with or without anything in the for loop:
int bar() {
std::string s = "s";
for (int i = 0; i < s.size(); i++) {
std::cout << s[i] << std::endl;
}
return 0;
}
I am using the C++14 standard and the same code used to work on other compilers/older versions of VS. The same problem exists for any string size (although that should be irrelevant). I understand I could modify the code to use and dereference pointer instead of using int, but want to understand why this doesn't work anymore, why is it unsafe or incorrect, or what else am I missing. Thanks!
Commenting out the cout line gives infinite loop warning and indeed enters infinite loop
s.size() is an unsigned long so it can never be less than 0. The behavior of narrowing conversion due to assignment of unsigned long to int is implementation defined behavior though it should not be a problem when assigning unsigned long value 0 to int, at least I wouldn't think so, but who knows, MSVC does have its quirks.
It appears the compiler is smart enough to predict that there cannot be an infinite loop when this particular body of the for loop is present, which leads me to believe that an exception may be thrown when accessing the array, perhaps out of bounds access.
Using the debugger to track the value of i is your best bet to understand what is going on.
The issue was in fact originally caused by "auto" i rather than "int" i, but not properly refreshed. Auto gave i an unsigned int type, which overflowed the [] operator, or caused infinite loop turning over from zero to 18446744073709551615 once the i = 0 cycle completes and i-- is executed.
Thank you everyone for the helpful replies!
Could it be that your int defaults to being unsigned and therefore decrementing when i=0 resuts in a high value ?
As #PeteBecker mentioned, int should be signed and should not overflow. However my guess is that your actual code does not use int.
I just started learning C++. So, I cannot figure out why vector member function does not insert values into vector.
int main (){
vector<char> v(5);
char x = 'a';
for (int i = 0; i < v.size(); ++i) {
v.push_back(x);
++x;
}
for (int i = 0; i < v.size(); ++i)
cout << v[i];
keep_window_open();
return 0;
}
I cannot figure out why vector member function does not insert values into vector
It does insert the values in the fact. The execution, just doesn't reach the printing of vector contents, since the loop:
for (int i = 0; i < v.size(); ++i) {
v.push_back(x);
++x;
}
Is an infinite one.
Before the first iteration v.size() return 5 (since that is the number of elements, the vector was constructed with), hence the i < v.size() during the first iteration evaluate to 0 < 5.
The loop, then does its thing, by inserting the element into the vector (increasing the v.size() by 1 in the process), and increasing i by 1. Hence, the comparison during the second iteration evaluates to 1 < 6.
It, then, continues, in the similar fashion, towards infinity (or until you kill it).
#juanchopanza "Even if it were, UB could still leave you with an infinite loop." - That's not how UB works. If a program has UB anywhere, the entire program is invalid and any behaviour is OK. Doing what you intended, an infinite loop, a crash, formatting your harddrive. All are OK results of a program invoking UB.
I'm working on a program to solve an Economics model. First, I declare a namespace as follows:
namespace myNameSpace
{
const int d1{10};
const int d2{5};
const int d3{7};
double array[d1][d2][d3]={};
}
Then, I have a function that modifies array:
void doSomething(double (&array)[myNameSpace::d1][myNameSpace::d2][myNameSpace::d3])
{
int i,j,k;
for (i=0, j=0, k=0; i<myNameSpace::d1,j<myNameSpace::d2,k<myNameSpace::d3; i++,j++,k++)
array[i][j][k]=i+j+k+1.0;
}
In the main function I call doSomething as:
int main()
{
doSomething(myNameSpace::array);
for (int i=0;j<myNameSpace::d1;j++)
std::cout << myNameSpace::array[i][1][1] << std::endl;
}
The output I get in the console is:
0
0
0
Can you provide any guidance on this? I've tried passing array without the address-of operator &, but then inside doSomething, array losses the first dimension. Any help will be highly appreciated!!
First of all, your for loop
for (i=0, j=0, k=0; i<myNameSpace::d1,j<myNameSpace::d2,k<myNameSpace::d3; i++,j++,k++)
doesn't do what you think it does, and you would've (hopefully) noticed that if you compiled with warnings (warning: relational comparison result unused).
It has 2, related, major problems:
Since i<myNameSpace::d1,j<myNameSpace::d2,k<myNameSpace::d3 only returns the value of the last comparison, due to the comma operator being used. So, you are effectively iterating until k<myNameSpace::d3.
The for loop you wrote - is just a single loop. It doesn't iterate through all possible combinations of values of i, j, and k, as you might have wanted.
It initializes i, j, k to 0; checks comparison expression (which, as explained by (1) only checks the value of k); and after the code in the loop was run - increments all of i, j, k by 1. Hence - you are setting only the 0/0/0, 1/1/1, 2/2/2, ..., up until k/k/k indices of your array. And, because your middle array has a bound, which is smaller than k - you invoke undefined behavior by stepping out of bounds.
And, lastly, you are printing only the i/1/1 index of your array, and since the only one value in the index range 0/1/1-d1/1/1 that's set is 1/1/1 - it is, exactly what's printed with a non-zero value.
To iterate over the whole array, as, might have been your intention - you should use nested loops, so they would allow all of the loop variables to change independently of one another:
for (i=0; i<myNameSpace::d1; i++)
{
for (j=0; j<myNameSpace::d2; j++)
{
for (k=0; k<myNameSpace::d3; k++)
{
array[i][j][k]=i+j+k+1.0;
}
}
}
for start you have a problem with your for loop
initialize i and running over j. once I changed it, I received some values.
If your array declared with those sizes it's way shorter (and readable)to write:
void doSomething( declspec(myNameSpace::array) &array )
or much better to declare type alias to use it everywhere:
using myArrayType = double[myNameSpace::d1][myNameSpace::d2][myNameSpace::d3];
not to mention that d1,d2 and d3 should be const. Toset ALL elements of array your loops should look like this:
void doSomething( myArrayType &array )
{
int i,j,k;
for ( i = 0; i < myNameSpace::d1; i++)
for ( j = 0; j < myNameSpace::d2; j++)
for (k = 0; k < myNameSpace::d3; k++)
array[i][j][k]=i+j+k+1.0;
}
Everything written in single for divided by comma is happening in single iteration. There are perverted ways to write it in single for() but I don't recommend that code.
for() loop is very flexible. pretty much it looks like
for(expressionFirst; expressionCheck; expressionEach )
statement to execute
expressionFirst can be ANY statement OR a single declaration, it executes only once, before loop starts. expressionCheck executed at beginning of each iteration, it must be any expression that is contextually convertible to bool (i.e. if even explicit T::operator bool() const; is applicable in this case), if it returns false, the loop stops. expressionEach is any expression that evaluates at end of each iteration.
Equivalent of for()
{
expressionFirst
while ( expressionCheck )
{
statement to execute
expressionEach;
}
}
All expressions are optional, so you can use for(;;) - a "forever" loop.
Comma operator you use allows to sequence several expressions, only last one is returned as result. Thus it is called sequence operator. And that's why your loop is wrong.
And you have a typo in main function, which led you to print only the first element of array, no increment of i.
I tried to compile your code, and I got an error in this line:
for (int i=0;j<myNameSpace::d1;j++)
The variable j is undeclared. As you can note, you declared the variable i inside the for loop, but not j. Do you want to loop using i or j? ...Maybe it's i because inside the body of the loop you used it as first-dimension index?
So, maybe you meant this code?
for (int i = 0; i < myNameSpace::d1; i++)
std::cout << myNameSpace::array[i][1][1] << std::endl;
In addition, are you sure the loop inside doSomething does what you mean?
Or maybe you want to loop using three nested loops for each array dimension?
E.g.:
void doSomething(double (&array)[myNameSpace::d1][myNameSpace::d2][myNameSpace::d3])
{
for (int i = 0; i < myNameSpace::d1; i++) {
for (int j = 0; j < myNameSpace::d2; j++) {
for (int k = 0; k < myNameSpace::d3; k++) {
array[i][j][k] = i + j + k + 1.0;
}
}
}
}
Note that in C++ raw arrays are passed by reference, so the &array syntax is unnecessary. Moreover, the compiler also ignores the raw array dimensions (myNameSpace::d1, etc.) for array parameters. Those may be good for documentation purposes though.
I am beginner in C++. What I understand is that:-
i++ is executing first, then increment, ++i is increment first, then execute,i+=1 is increment by 1,then execute. But in the FOR loop:
for (i=0;i<10;i++)
for (i=0;i<10;++i)
There is really no difference in these two loops above.
Here is another one to calculate the sum of all integers from 1 to 100:
int i=1, sum=0;
while (i<=100)
{
sum+=i;
i++; //i+=1; ++i;
}
cout<<sum<<" "<<i<<endl;
return 0;
But if I replace i++ with i+=1 or ++i, they all return a sum of 5050 and i of 101. So I really don't see any difference in them.
So could anyone explain this to me? Which one of those is used most in programming? Thank you!!
You are correct. In your examples there is no difference.
But here there is:
int i = 0;
cout << i++ << endl; //prints 0
cout << i << endl; //prints 1
vs
int i = 0;
cout << ++i << endl; //prints 1
cout << i << endl; //prints 1
Which one of those is used most in programming?
Most of the time, ++ is the only operation in the statement (FYI, a for loop has three statements).
If it isn't, then it might matter, and you'll use whichever one gives you the correct behavior.
FYI
Some developers have the opinion that if pre and postfix operators should always be used alone (not part of a large statement). They can lead to confusing code, or even undefined behavior.
For example,
int i = 0;
cout << i++ + i++ << endl;
has undefined behavior.
So could anyone explain this to me?
What i++ does is return the current value of i and then increment it by one, and ++i first increment i by 1 and then returns the value of i.
Take a look at this, for example:
i = 5;
j = 5;
res = i++; //res = 5, but i=6
res = ++j; //res = 6 and j=6
Which one of those is used most in programming?
Both are used depending on what you want or may be how you want.
One more thing to note:
++i is an l-value, but i++ is not. For details see here
Your analysis is correct. i++ will return the value of i, then increment, whereas ++i will increment the value of i, then return the new value. i += 1 will do the same as ++i. The difference in where they will be used in actual code is primarily situational; there's no specific answer as to where each of them are most often used or helpful. It all depends on what you want to do.
Here's a contrived example of one time it might be useful to use post-increment (i++ form):
// Return the length of a string, including the null byte
int stringLength(char str[])
{
int length = 0;
while (str[length++] != 0);
return length;
}
If you wanted to return the length without the null byte, you could modify the above example slightly, using the ++i form:
// Return the length of a string, without the null byte
int stringLength(char str[])
{
int length = -1;
while (str[++length] != 0);
return length;
}
As for i += 1, I don't think I've ever done quite that, since you can use pre- or post-increment instead. I've generally only used the compound assignment operators for values other than 1.
I think if you imagine how the for loop works you can understand the problem at hand.
for loop
initialization --> i = 0
<check condition> --> i<10? ------->--------------------
| | |
^ |yes(i.e condition not met) |no(i.e condition met)
| V V
| --------------
| |body of loop|
| --------------
| |
| V
-------<------------increment i (**) exit for loop
** increment i means i++ or ++i
i++ can be replaced by this :
int temp = i;
i = i + 1;
temp will be useless here so the compiler will optimize it to just inc i instruction. even if it doesn't do that temp is just a waste of space that's all.
++i can be replaced by
i = i + 1;
int temp = i;
again temp is not required so the compiler will just replace it with inc i instruction.
if you see both the instruction are the same because they are not being assigned to anything. only i is being affected by the increment. so both are essentially the same. this is true if i is a built-in type .
you see that the increment instruction is placed after the body of the loop? can you now see that this is almost similar to the while loop that you showed?
it is always nice to think of loops in this way.
I am writing a get function within a class of an object oriented program, but the i++ in my code is not executing for some reason.
This is what is used in my .cpp file:
char MyString::Get(int i)
{
if( i = '\0')
{
exit(1);
}
else
{
return String[i];
}
}
This is what is called in the main.cpp file:
for(int i=0; i < String1.Length()+1; i++)
{
cout<< String1.Get(i)<<" ";
}
cout << endl;
This is the length method in the .cpp file for reference purposes:
int MyString::Length()
{
int counter(0);
while(String[counter] != '\0')
{
counter ++;
}
return (counter);
}
Also: String1 = Jello World
The output:
J J J J J J J J J J J J J
Well - probably cause of this. You assigned instead of compared. You assigned zero to i. That failed the 'if' test (it's zero), so exit did not get called and the rest of your routine ran with i == to zero.
if( i = '\0')
{
exit(1);
}
You haven't really shown enough code for someone to be able to figure out what your code is doing, but this looks incorrect:
if( i = '\0')
a single = symbol causes i to be assigned the value on the right-hand-side of the expression.
if( '\0' ) evaluates to if(false).
As others have pointed out, you're doing an assignment instead of a comparison, so the "comparison" will always be treated as false -- the result of a comparison is the assigned value, which in this case is 0.
Though it has never become overwhelmingly popular, there is a fairly simple technique to avoid this problem: when you're comparing to a constant, always put the constant on the left. This way, if you mis-type == as =, the code won't compile:
if ('\0' = i) // error: lvalue required (or something on that order).