-1

I have an array of strings arr[5][8] = {...} (every string was declared) and I am trying to understand what value of arr[3] - arr[2] is and what is its type. I cannot understand why a difference between addresses are considered in bytes, because when I print this: printf("%d\n" , names[2] - names[1]) I get 8.

Why does it behaves like this? A full code example below:

#include <stdio.h>     
int main()
{
    char names[5][8] = { "Miri", "Tali", "Ronit", "Avigail", "Shlomit" };
    printf("%d\n", names[2] - names[1]);
    system("pause");
    return 0;
}

The output is 8.

8 is exactly the distance from names[1] to names[2] in bytes (there are 8 chars in every string, every char is 1 byte). But I put %d and thought that this distance will be printed in the decimal representation of these bytes. In other words, I thought the result to be 8*255, because the max value that can be represented in 1 byte is 255 and here I have 8 bytes (chars).

DeiDei
  • 10,205
  • 6
  • 55
  • 80
Lev
  • 43
  • 4
  • "I cannot understand why a difference between addresses are considered in bytes" - If not considered in bytes, in what other? In bits, kilometers, or liters? Why 8 * 255 and not 8 * 256? What is 255? – i486 Feb 13 '18 at 10:11

4 Answers4

3

In your case, names[i] is an array of characters, the type being char[8].

                +-----------------------------------------------------------+
names [0]       |                                                           |
                +-----------------------------------------------------------+
                1000    1001    1002    1003    1004    1005    1006    1007

                +-----------------------------------------------------------+
names [1]       |                                                           |
                +-----------------------------------------------------------+
                1008    1009    1010    1011    1012    1013    1014    1015

                +-----------------------------------------------------------+
names [2]       |                                                           |
                +-----------------------------------------------------------+
                1016    1017    1018    1019    1020    1021    1022    1023

So, when you say names[2] - names[1], basically, you're subtracting two array members, having 8 elements.

In other words, you're subtracting two pointers where each of them is a pointer to the first element of an array type, holding 8 elements each. Hence, the difference is 8.

This has nothing to do with the value stored at the memory location pointer to by the pointers themselves, you are operating on pointers and not the values pointed to by the pointers. Pointer arithmetic rules will be applicable here.

That said, to print the result of pointer subtraction, you should use %td as conversion specifier, the type would be ptrdiff_t.

Quoting C11, chapter §6.5.6

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. [....]

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
1

Your code has undefined behavior, since you're mis-matching the type of your value with the type specified in the printf() conversion. The type of the difference is ptrdiff_t, but %d needs a value of type int.

The rest of your reasoning is hard to follow, unfortunately. The maximum value of a byte has nothing to do with the difference between two addresses.

unwind
  • 391,730
  • 64
  • 469
  • 606
1

The in-memory view of char array names will be like this:

       names
  100  +-+-+-+-+-+-+-+-+
       |M|i|r|i|0|0|0|0|
  108  +-+-+-+-+-+-+-+-+
       |T|a|l|i|0|0|0|0|
  116  +-+-+-+-+-+-+-+-+
       |R|o|n|i|t|0|0|0|
  124  +-+-+-+-+-+-+-+-+
       |A|v|i|g|a|i|l|0|
  132  +-+-+-+-+-+-+-+-+
       |S|h|l|o|m|i|t|0|
       +-+-+-+-+-+-+-+-+

//100, 108.. are addresses

names[2] is Ronit and names[1] is Tali.
Now, hope you understood why names[2] - names[1] is giving 8, if not then try changing names array dimension 8 to 9:

char names[5][9] = ...

and check the result.

H.S.
  • 11,654
  • 2
  • 15
  • 32
0

For understanding this fully, you'll need to know how memory is addressed, how this program is being stored in the memory, etc. See this for more on that -

Difference between word addressable and byte addressable

To answer your question, consider memory to be comprised of individual blocks where every block is 1 byte long. So -

8 it's exactly a distance from names[1] to names[2] in bytes(There are 8 chars in every string, every char is 1 byte)

is correct and is the reason why you are getting 8 as an answer here.

thought that this distance will be printed in the decimal representation of these bytes

255 is not the decimal representation of these bytes. Instead it is the max value that every single byte can hold (2^8 - 1). I hope this helps.

k10
  • 1
  • 3