char and pointers

This is probably really simple, and I just can't see it, but can someone explain why the code works... Basically why the -2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
  //
//  main.cpp
//  pointers
//
//  Created by James Farrow on 12/02/2017.
//  Copyright © 2017 James Farrow. All rights reserved.
//

#include <iostream>


int main() {

 char text[] = "This";
    int charLength = sizeof(text);// c++ appends termination char to end, therefore - 1 is needed.
    
    char *textPtrStart = text;
    char *textPtrEnd = text + sizeof(text) - 2; //why does end of pointer need -2?
    
    std::cout << std::endl;
    
    std::cout << textPtrStart << std::endl;
    std::cout << textPtrEnd << std::endl;
    
    std::cout << charLength << std::endl;
    
    return 0;
}

Last edited on
c strings are zero terminated.

so "hey" is stored as hey0

sizeof returns the size in bytes of the pointer, which is 4 here.

the length of the string is 3 to humans, so -1 as stated on line 15.

but c++ also starts index at zero.

so the index into the pointer is
h e y 0 <- string
0 1 2 3 <- offset in c
1 2 3 4 <- humans and sizeof

to get the pointer to the last letter, you need pointer position #2, the offset in c value for y. It works out that the size in bytes (4) - 2 (constant) = offset of last letter (2), see?

and, this is sort of ugly. use strlen(variable).







Last edited on
The "need" depends on what you [i]need[i].

Remember that these two syntaxes dereference the same object:
1
2
text[3]
*(text+3)



The array text has 5 elements: {'T', 'h', 'i', 's', 0}
The last element of the array, text[4], is the terminating null.

The textPtrStart points to element text[0]

text+5 would point to text[5], which is one past the end.
text+5-1 == text+4 would point to text[4], which is the last element.
text+5-2 == text+3 would point to text[2], which is the last character before the terminating null.

Note that:
1
2
char text[] = ""; // 1-element array
char *foo = text + sizeof(text) - 2; // == text-1, which is out-of-range 



You apparently want to print the last character of the string (or print the string starting from the last character). For that you have to point to the character that you want.
So what you are saying is ditcg sizeof() and use strlen() instead as below. It's just easier.
Thank you for your answer - very well explained. It maked a lot of sense now, whereas I couldn't fathom it before!!

Thing is using xcode I do not need to include <string.h> for strlen to work...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
  //
//  main.cpp
//  pointers
//
//  Created by James Farrow on 12/02/2017.
//  Copyright © 2017 James Farrow. All rights reserved.
//

#include <iostream>
#include <string.h>


int main() {

 char text[] = "This";
    int charLength = strlen(text);
    
    char *textPtrStart = text;
    char *textPtrEnd = text + strlen(text) - 1; //use -1 here because of 0 termination stated previously.
    
    std::cout << std::endl;
    
    std::cout << *textPtrStart << std::endl;
    std::cout << *textPtrEnd << std::endl;
    
    std::cout << charLength << std::endl;
    
    return 0;
}
Last edited on
it isn't easier, its one line of code either way. Its cleaner. The first program is pointer magic, and when you see that in the middle of code out of nowhere, you have to stop to figure out what the heck the author was doing. If looking for a bug, this gets old fast.

Strlen tells the reader what you are doing by its name.


try this code.

char c[100];
strcpy(c, "oops");
cout << sizeof(c) << endl;
cout << strlen(c) << endl;

that should highlight the issue. Can you see that the sizeof() trick only works on constant strings?



Last edited on
Cheers I think I've got it!!

char c[100] is an array of 100 characters - fixed. sizeof will always return 100 regardles of what is in the array.
Yet strlen actually returns the amount of characters in the array?
right!
Topic archived. No new replies allowed.