Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pointer operation yields unexpected result

I was expecting the code below to print 4 (since a float is 4 bytes), but it prints 1. Would someone explain why this happens?

#include <stdio.h>
int main()
{
    float a[4]={0.0,0.1,0.2,0.3};
    printf("%d", &a[1]-&a[0]);
    return 0;
}
like image 214
guhet5ty3984wefjn Avatar asked Feb 19 '26 18:02

guhet5ty3984wefjn


2 Answers

First of all, change

  printf("%d", &a[1]-&a[0]);

to

 printf("%td", &a[1]-&a[0]);

as the result type of two subtraction yields a type ptrdiff_t and %td is the conversion specifier for that type.

That said, quoting C11, chapter §6.5.6, subtraction operator (emphasis mine)

When two pointers are subtracted, both shall point to elements of the same array object, or one past the last element of the array object; the result is the difference of the subscripts of the two array elements. [....] In other words, if the expressions P and Q point to, respectively, the i-th and j-th elements of an array object, the expression (P)-(Q) has the value i−j provided the value fits in an object of type ptrdiff_t. [....]

In your case, P is &a[1] and Q is &a[0], so i is 1 and j is 0. Hence the result of the subtraction operation is i-j, i.e., 1-0, 1.

like image 63
Sourav Ghosh Avatar answered Feb 22 '26 06:02

Sourav Ghosh


You are correct that the two pointers are 4 bytes apart. And if you were subtracting two integers you'd get 4. But &a[1] and &a[0] are of type float *. Pointer arithmetic in C takes into account the size of the thing being pointed to, so &a[1]-&a[0] is 1.

This is the basic means by which array indexing works. You can take advantage of this to iterate through an array without needing a separate index and instead terminating on a boundary such as NaN.

#include <stdio.h>
#include <math.h>

int main()
{
    float a[] = { 0.0,0.1,0.2,0.3,NAN };

    float *iter = a;
    while(!isnan(*iter)) {
        printf("%f\n", *iter);
        iter++;
    }
}

If you instead cast the values to unsigned int you will indeed get 4.

printf("%u\n", (unsigned int)&a[1]-(unsigned int)&a[0]);
like image 34
Schwern Avatar answered Feb 22 '26 07:02

Schwern