vector<int> v;
cout<<v.size()-1;
The following will give you 18446744073709551615
. This is because vector.size()
returns a size_t
type value, which is an alias for unsigned long int
. In plain terms:
unsigned long int a=0;
cout<<a-1;
The above code will give the same result — 18446744073709551615
.
Implications
for(int i=0;i<vector.size()-1;i++){
...
}
In the above for loop, if the vector has 0 elements, then the loop will be equivalent to:
for(int i=0;i<18446744073709551615;i++){
...
}
Which, I believe is not what you will be expecting. So the correct way to use for loops is the following:
for(int i=0;(i+1)<vector.size();i++){
...
}
---Edit---
As pointed out by Errichto and satyaki3794, we can just typecast vector.size() to an int, and use it normally. Like this:
for(int i=0;i<(int)vector.size()-1;i++){
...
}
easier to read:
You can just typecast vector.size() to an int instead. Then it will always give the correct value.
=>
Because it's not a good idea to use signed number, when there is no need to use negative values.
Suppose I need to iterate backward. I do not think making size_t unsigned was a good idea
That is a matter of taste. I prefer to use the following:
That's unreadable. Really
you really suppose using
i - 1
superior?I would understand if you've said
for (size_t i = a.size(); i-- > 0;)
but it's still not really readableWhy does the vector.size() give correct answer when the vector has non zero elements?
vector.size() always gives a correct answer. If you have an empty vector, it will return size = 0. However, since it returns the answer in an unsigned format, if you minus one from 0, it overflows since unsigned numbers can't be negative.
So when overflows the output will be maximum value of unsigned long long?
Yeah.
Can you give more insights via bit level calculations ?
Signed numbers use the first bit to tell if the number is negative or positive, while unsigned numbers use the first bit like any other bit. Ex. 101 would be 5 for an unsigned number, but -3 for a signed number. Integers use a system called two's complement to store negative numbers. Essentially how the system works is if I have a number N, -N = (reverse all bits of N) + 1. So when an unsigned long long number tries to do this with -1, it flips all the bits, changing the number like so: (binary representation of 1 = 0.....001) -> (1.....110). When you add 1 to this, all the bits are set to 1, thus giving you the maximum value of unsigned long long.
or you can use
but this is better
C++20 contains the method
ssize
which returns an int value for the vector size. See https://en.cppreference.com/w/cpp/iterator/size for details. I hope to see C++20 soon here on Codeforces :).