Your code is clear in my opinion, I will suggest some improvements that are not really necessary on this scale but will help when you will start dealing with more complex and longer code:
Commenting the why
What are these lines doing:
if (*v1) v1++;
if (*v2) v2++;
They are skipping the dot right? This explains why you are doing the comparison and incrementing the counter, so add a comment:
// Skip the dots
if (*v1) v1++;
if (*v2) v2++;
Self descriptive names
a
and b
are very generic names that could represent anything, I renamed them v1_current
and v2_current
Modularity
What is
while (*v1 && *v1 != '.') a = 10*a + (*v1++ - '0');
doing? It is updating the value of a adding the value found between two dots, this can be extracted into a function to be tested separately to increase the robustness and readability of the code:
void update_count(const char * version, int *current_count) {
// Update the current count with the value between the dots.
while (*version && *version != '.') (*current_count) = 10*(*current_count) + (*version++ - '0');
}
Automatic testing
How can I be sure that I did not break anything while doing these changes? A very lightweight automated testing using assert
can benefit even simple project to making it simpler to both optimize and refactor the code.
Final revision
Here I applied all the improvements, the code is longer, but much of the added length are tests that can double as documentation for a potential future user and the helper function, that is a good practice.
#include <stdio.h>
#include <assert.h>
void update_count(const char * version, int *current_count) {
// Update the current count with the value between the dots.
while (*version && *version != '.') (*current_count) = 10*(*current_count) + (*version++ - '0');
}
int compareVersion(const char * v1, const char * v2)
{
// Compare two version numbers of the form
// dd.d.dd where d is a digit (ex: 2.1.3 is bigger than 1.2.1)
// Returns:
// +1 if the first version number is bigger than the second one
// -1 if the second one is bigger
// 0 if they are equal
while (*v1 || * v2)
{
int v1_current=0, v2_current=0;
// Read the number between two dots (or the first or last one)
update_count(v1, &v1_current);
update_count(v2, &v2_current);
// Skip the dots
if (*v1) v1++;
if (*v2) v2++;
// +1 if the first version number is bigger than the second one
if (v1_current < v2_current) return -1;
if (v1_current > v2_current) return +1;
}
return 0;
}
int main() {
int a = 0;
update_count("1.0.32", &a);
assert(a == 1);
int b = 0;
update_count("23.4.1", &b);
assert(b == 23);
assert(compareVersion("1.0.32", "1.0.32") == 0);
assert(compareVersion("1.0.32", "1.0.33") == -1);
assert(compareVersion("1.0.36", "1.0.34") == 1);
assert(compareVersion("2.0.32", "1.0.32") == 1);
}
2
vs.2.0
...? Is the no–number less than zero, or equal zero? \$\endgroup\$