Search code examples
catoi

Is the atoi function really efficient to compare an integer and a string?


I'm currently trying to make a function containing an "if" sequence.The condition of this if is linked to command line arguments as my function should only if the third command line argument passed is the number '0'. My current problem is that the atoi() function return 0 in case of failure making my function works even when the third arguments is a letter or a random character.That's why i'm wondering if the problem is the atoi() function or my lack of comprehension about command line arguments. Here is an example of my code:

int encryption_case(int ac, char **av)
{
    if(atoi(av[3]) == 0){
         print_matrix(av[2]);
    } else {
    exit (84);
    }
}

I also tried working without the atoi function but the comparison between av and a number is tricky for me.I would greatly appreciate even if not the direct answer to be redirect to a website to solidify my basics in c.


Solution

  • Using atoi to test whether a string is “0” is inefficient.

    Whether a C string is “0” is determined by:

    • The first byte is '0'.
    • The second byte is zero.

    This is fundamentally a test of two bytes or, if the platform permits, a test of 16 bits, and so it should be an operation that is at most loading a byte, comparing it, branching based on the result, loading a second byte, comparing it, and branching based on the result. In contrast, atoi involves a function call, establishing a stack frame, possibly initializing local data in preparation for numerical conversion work, loading the first byte, checking whether it is a white space character, then checking whether it is “-” or a digit, and so on, followed by popping the stack frame and returning. It is almost certainly more work than the simple string comparison required.

    … the comparison between av and a number is tricky for me.

    We can perform the test described above this way:

    const char *p = av[3];           // Save av[3] in a pointer for convenience.
    if (p[0] == '0' && p[1] == '\0') // Test for “0” digit followed by null character.
        print_matrix(av[2]);
    …
    

    We could also use the strcmp function in the standard C library:

    #include <string.h>
    
    …
    
    if (0 == strcmp(av[3], "0"))
        print_matrix(av[2]);
    …
    

    That nominally involves a function call and so may be less efficient than the manual test. However, with -O3, both Clang and GCC compile it to a direct test of the two bytes, at least for some target platforms.