Often using C array indexing has benefits over using pointers:
- Can be the same speed or faster code. Compiler does a good job.
- Code easier to comprehend.
- Log / instrumentation easier to comprehend.
- Special debug log / instrumentation easier to write and comprehend.
- Assert()s easier to write.
Recently came across this [1] shorter example C code which finds the searches a string for the longest substring without repeating characters.
The code is shorter and particularly difficult to understand, and there were comments on leetcode complaining that the code is difficult to understand. The attached code on this page makes the following changes:
- Creates an optional debug version of the original pointer based code.
- Creates an array indexed version of the code which optional debug version.
- Creates a slightly enhanced version of the code for the case that the string length is also passed.
- Creates a simple harness to time the non-debug version.
$ gcc -DDEBUG=1 -O1 -o length-of-longest-substring length-of-longest-substring.c && ./length-of-longest-substring
- searching string: abcabcbb
- temp < s (nil)=temp 0x7ffd1a264770=s 0x7ffd1a264770=end=abcabcbb 0=len
- temp < s (nil)=temp 0x7ffd1a264770=s 0x7ffd1a264771=end=bcabcbb 0=len
- temp < s (nil)=temp 0x7ffd1a264770=s 0x7ffd1a264772=end=cabcbb 0=len
- temp >= s 0x7ffd1a264770=temp 0x7ffd1a264770=s 0x7ffd1a264773=end=abcbb 3=len
- temp >= s 0x7ffd1a264771=temp 0x7ffd1a264771=s 0x7ffd1a264774=end=bcbb 3=len
- temp >= s 0x7ffd1a264772=temp 0x7ffd1a264772=s 0x7ffd1a264775=end=cbb 3=len
- temp >= s 0x7ffd1a264774=temp 0x7ffd1a264773=s 0x7ffd1a264776=end=bb 3=len
- temp >= s 0x7ffd1a264776=temp 0x7ffd1a264775=s 0x7ffd1a264777=end=b 3=len
- 3=len longest substring in string b
- searching string: bbbbb
- temp < s (nil)=temp 0x7ffd1a264750=s 0x7ffd1a264750=end=bbbbb 0=len
- temp >= s 0x7ffd1a264750=temp 0x7ffd1a264750=s 0x7ffd1a264751=end=bbbb 1=len
- temp >= s 0x7ffd1a264751=temp 0x7ffd1a264751=s 0x7ffd1a264752=end=bbb 1=len
- temp >= s 0x7ffd1a264752=temp 0x7ffd1a264752=s 0x7ffd1a264753=end=bb 1=len
- temp >= s 0x7ffd1a264753=temp 0x7ffd1a264753=s 0x7ffd1a264754=end=b 1=len
- 1=len longest substring in string b
- searching string: pwwkew
- temp < s (nil)=temp 0x7ffd1a264760=s 0x7ffd1a264760=end=pwwkew 0=len
- temp < s (nil)=temp 0x7ffd1a264760=s 0x7ffd1a264761=end=wwkew 0=len
- temp >= s 0x7ffd1a264761=temp 0x7ffd1a264760=s 0x7ffd1a264762=end=wkew 2=len
- temp < s (nil)=temp 0x7ffd1a264762=s 0x7ffd1a264763=end=kew 2=len
- temp < s (nil)=temp 0x7ffd1a264762=s 0x7ffd1a264764=end=ew 2=len
- temp >= s 0x7ffd1a264762=temp 0x7ffd1a264762=s 0x7ffd1a264765=end=w 3=len
- 3=len longest substring in string kew
- searching string: abcdeabc
- temp < s (nil)=temp 0x7ffd1a264780=s 0x7ffd1a264780=end=abcdeabc 0=len
- temp < s (nil)=temp 0x7ffd1a264780=s 0x7ffd1a264781=end=bcdeabc 0=len
- temp < s (nil)=temp 0x7ffd1a264780=s 0x7ffd1a264782=end=cdeabc 0=len
- temp < s (nil)=temp 0x7ffd1a264780=s 0x7ffd1a264783=end=deabc 0=len
- temp < s (nil)=temp 0x7ffd1a264780=s 0x7ffd1a264784=end=eabc 0=len
- temp >= s 0x7ffd1a264780=temp 0x7ffd1a264780=s 0x7ffd1a264785=end=abc 5=len
- temp >= s 0x7ffd1a264781=temp 0x7ffd1a264781=s 0x7ffd1a264786=end=bc 5=len
- temp >= s 0x7ffd1a264782=temp 0x7ffd1a264782=s 0x7ffd1a264787=end=c 5=len
- 5=len longest substring in string deabc
- searching string: Iamhappy
- temp < s (nil)=temp 0x7ffd1a264790=s 0x7ffd1a264790=end=Iamhappy 0=len
- temp < s (nil)=temp 0x7ffd1a264790=s 0x7ffd1a264791=end=amhappy 0=len
- temp < s (nil)=temp 0x7ffd1a264790=s 0x7ffd1a264792=end=mhappy 0=len
- temp < s (nil)=temp 0x7ffd1a264790=s 0x7ffd1a264793=end=happy 0=len
- temp >= s 0x7ffd1a264791=temp 0x7ffd1a264790=s 0x7ffd1a264794=end=appy 4=len
- temp < s (nil)=temp 0x7ffd1a264792=s 0x7ffd1a264795=end=ppy 4=len
- temp >= s 0x7ffd1a264795=temp 0x7ffd1a264792=s 0x7ffd1a264796=end=py 4=len
- temp < s (nil)=temp 0x7ffd1a264796=s 0x7ffd1a264797=end=y 4=len
- 4=len longest substring in string py
- 16=total for 1 calls to lengthOfLongestSubstringViaPtrs() with strings "abcabcbb", "bbbbb", "pwwkew", "abcdeabc", and "Iamhappy" in 0.000107 seconds
- searching string: abcabcbb
- last_pos_of_c < pos_substring_1st -1=last_pos_of_c 0=pos_substring_1st 0=pos=abcabcbb 0=len 'a'@0
- last_pos_of_c < pos_substring_1st -1=last_pos_of_c 0=pos_substring_1st 1=pos=bcabcbb 0=len 'a'@0 'b'@1
- last_pos_of_c < pos_substring_1st -1=last_pos_of_c 0=pos_substring_1st 2=pos=cabcbb 0=len 'a'@0 'b'@1 'c'@2
- last_pos_of_c >= pos_substring_1st 0=last_pos_of_c 0=pos_substring_1st 3=pos=abcbb 3=len 'a'@3 'b'@1 'c'@2
- last_pos_of_c >= pos_substring_1st 1=last_pos_of_c 1=pos_substring_1st 4=pos=bcbb 3=len 'a'@3 'b'@4 'c'@2
- last_pos_of_c >= pos_substring_1st 2=last_pos_of_c 2=pos_substring_1st 5=pos=cbb 3=len 'a'@3 'b'@4 'c'@5
- last_pos_of_c >= pos_substring_1st 4=last_pos_of_c 3=pos_substring_1st 6=pos=bb 3=len 'a'@3 'b'@6 'c'@5
- last_pos_of_c >= pos_substring_1st 6=last_pos_of_c 5=pos_substring_1st 7=pos=b 3=len 'a'@3 'b'@7 'c'@5
- 3=len longest substring in string abcabcbb
- searching string: bbbbb
- last_pos_of_c < pos_substring_1st -1=last_pos_of_c 0=pos_substring_1st 0=pos=bbbbb 0=len 'b'@0
- last_pos_of_c >= pos_substring_1st 0=last_pos_of_c 0=pos_substring_1st 1=pos=bbbb 1=len 'b'@1
- last_pos_of_c >= pos_substring_1st 1=last_pos_of_c 1=pos_substring_1st 2=pos=bbb 1=len 'b'@2
- last_pos_of_c >= pos_substring_1st 2=last_pos_of_c 2=pos_substring_1st 3=pos=bb 1=len 'b'@3
- last_pos_of_c >= pos_substring_1st 3=last_pos_of_c 3=pos_substring_1st 4=pos=b 1=len 'b'@4
- 1=len longest substring in string bbbbb
- searching string: pwwkew
- last_pos_of_c < pos_substring_1st -1=last_pos_of_c 0=pos_substring_1st 0=pos=pwwkew 0=len 'p'@0
- last_pos_of_c < pos_substring_1st -1=last_pos_of_c 0=pos_substring_1st 1=pos=wwkew 0=len 'p'@0 'w'@1
- last_pos_of_c >= pos_substring_1st 1=last_pos_of_c 0=pos_substring_1st 2=pos=wkew 2=len 'p'@0 'w'@2
- last_pos_of_c < pos_substring_1st -1=last_pos_of_c 2=pos_substring_1st 3=pos=kew 2=len 'k'@3 'p'@0 'w'@2
- last_pos_of_c < pos_substring_1st -1=last_pos_of_c 2=pos_substring_1st 4=pos=ew 2=len 'e'@4 'k'@3 'p'@0 'w'@2
- last_pos_of_c >= pos_substring_1st 2=last_pos_of_c 2=pos_substring_1st 5=pos=w 3=len 'e'@4 'k'@3 'p'@0 'w'@5
- 3=len longest substring in string pwwkew
- searching string: abcdeabc
- last_pos_of_c < pos_substring_1st -1=last_pos_of_c 0=pos_substring_1st 0=pos=abcdeabc 0=len 'a'@0
- last_pos_of_c < pos_substring_1st -1=last_pos_of_c 0=pos_substring_1st 1=pos=bcdeabc 0=len 'a'@0 'b'@1
- last_pos_of_c < pos_substring_1st -1=last_pos_of_c 0=pos_substring_1st 2=pos=cdeabc 0=len 'a'@0 'b'@1 'c'@2
- last_pos_of_c < pos_substring_1st -1=last_pos_of_c 0=pos_substring_1st 3=pos=deabc 0=len 'a'@0 'b'@1 'c'@2 'd'@3
- last_pos_of_c < pos_substring_1st -1=last_pos_of_c 0=pos_substring_1st 4=pos=eabc 0=len 'a'@0 'b'@1 'c'@2 'd'@3 'e'@4
- last_pos_of_c >= pos_substring_1st 0=last_pos_of_c 0=pos_substring_1st 5=pos=abc 5=len 'a'@5 'b'@1 'c'@2 'd'@3 'e'@4
- last_pos_of_c >= pos_substring_1st 1=last_pos_of_c 1=pos_substring_1st 6=pos=bc 5=len 'a'@5 'b'@6 'c'@2 'd'@3 'e'@4
- last_pos_of_c >= pos_substring_1st 2=last_pos_of_c 2=pos_substring_1st 7=pos=c 5=len 'a'@5 'b'@6 'c'@7 'd'@3 'e'@4
- 5=len longest substring in string abcdeabc
- searching string: Iamhappy
- last_pos_of_c < pos_substring_1st -1=last_pos_of_c 0=pos_substring_1st 0=pos=Iamhappy 0=len 'I'@0
- last_pos_of_c < pos_substring_1st -1=last_pos_of_c 0=pos_substring_1st 1=pos=amhappy 0=len 'I'@0 'a'@1
- last_pos_of_c < pos_substring_1st -1=last_pos_of_c 0=pos_substring_1st 2=pos=mhappy 0=len 'I'@0 'a'@1 'm'@2
- last_pos_of_c < pos_substring_1st -1=last_pos_of_c 0=pos_substring_1st 3=pos=happy 0=len 'I'@0 'a'@1 'h'@3 'm'@2
- last_pos_of_c >= pos_substring_1st 1=last_pos_of_c 0=pos_substring_1st 4=pos=appy 4=len 'I'@0 'a'@4 'h'@3 'm'@2
- last_pos_of_c < pos_substring_1st -1=last_pos_of_c 2=pos_substring_1st 5=pos=ppy 4=len 'I'@0 'a'@4 'h'@3 'm'@2 'p'@5
- last_pos_of_c >= pos_substring_1st 5=last_pos_of_c 2=pos_substring_1st 6=pos=py 4=len 'I'@0 'a'@4 'h'@3 'm'@2 'p'@6
- last_pos_of_c < pos_substring_1st -1=last_pos_of_c 6=pos_substring_1st 7=pos=y 4=len 'I'@0 'a'@4 'h'@3 'm'@2 'p'@6 'y'@7
- 4=len longest substring in string Iamhappy
- 16=total for 1 calls to lengthOfLongestSubstringViaInts() with strings "abcabcbb", "bbbbb", "pwwkew", "abcdeabc", and "Iamhappy" in 0.000097 seconds
- searching string: abcabcbb of length 8
- last_pos_of_c < pos_substring_1st -1=last_pos_of_c 0=pos_substring_1st 0=pos=abcabcbb 0=len 'a'@0
- last_pos_of_c < pos_substring_1st -1=last_pos_of_c 0=pos_substring_1st 1=pos=bcabcbb 0=len 'a'@0 'b'@1
- last_pos_of_c < pos_substring_1st -1=last_pos_of_c 0=pos_substring_1st 2=pos=cabcbb 0=len 'a'@0 'b'@1 'c'@2
- last_pos_of_c >= pos_substring_1st 0=last_pos_of_c 0=pos_substring_1st 3=pos=abcbb 3=len 'a'@3 'b'@1 'c'@2
- last_pos_of_c >= pos_substring_1st 1=last_pos_of_c 1=pos_substring_1st 4=pos=bcbb 3=len 'a'@3 'b'@4 'c'@2
- last_pos_of_c >= pos_substring_1st 2=last_pos_of_c 2=pos_substring_1st 5=pos=cbb 3=len 'a'@3 'b'@4 'c'@5
- 3=len longest substring in string abcabcbb
- searching string: bbbbb of length 5
- last_pos_of_c < pos_substring_1st -1=last_pos_of_c 0=pos_substring_1st 0=pos=bbbbb 0=len 'b'@0
- last_pos_of_c >= pos_substring_1st 0=last_pos_of_c 0=pos_substring_1st 1=pos=bbbb 1=len 'b'@1
- last_pos_of_c >= pos_substring_1st 1=last_pos_of_c 1=pos_substring_1st 2=pos=bbb 1=len 'b'@2
- last_pos_of_c >= pos_substring_1st 2=last_pos_of_c 2=pos_substring_1st 3=pos=bb 1=len 'b'@3
- last_pos_of_c >= pos_substring_1st 3=last_pos_of_c 3=pos_substring_1st 4=pos=b 1=len 'b'@4
- 1=len longest substring in string bbbbb
- searching string: pwwkew of length 6
- last_pos_of_c < pos_substring_1st -1=last_pos_of_c 0=pos_substring_1st 0=pos=pwwkew 0=len 'p'@0
- last_pos_of_c < pos_substring_1st -1=last_pos_of_c 0=pos_substring_1st 1=pos=wwkew 0=len 'p'@0 'w'@1
- last_pos_of_c >= pos_substring_1st 1=last_pos_of_c 0=pos_substring_1st 2=pos=wkew 2=len 'p'@0 'w'@2
- last_pos_of_c < pos_substring_1st -1=last_pos_of_c 2=pos_substring_1st 3=pos=kew 2=len 'k'@3 'p'@0 'w'@2
- last_pos_of_c < pos_substring_1st -1=last_pos_of_c 2=pos_substring_1st 4=pos=ew 2=len 'e'@4 'k'@3 'p'@0 'w'@2
- 3=len longest substring in string pwwkew
- searching string: abcdeabc of length 8
- last_pos_of_c < pos_substring_1st -1=last_pos_of_c 0=pos_substring_1st 0=pos=abcdeabc 0=len 'a'@0
- last_pos_of_c < pos_substring_1st -1=last_pos_of_c 0=pos_substring_1st 1=pos=bcdeabc 0=len 'a'@0 'b'@1
- last_pos_of_c < pos_substring_1st -1=last_pos_of_c 0=pos_substring_1st 2=pos=cdeabc 0=len 'a'@0 'b'@1 'c'@2
- last_pos_of_c < pos_substring_1st -1=last_pos_of_c 0=pos_substring_1st 3=pos=deabc 0=len 'a'@0 'b'@1 'c'@2 'd'@3
- last_pos_of_c < pos_substring_1st -1=last_pos_of_c 0=pos_substring_1st 4=pos=eabc 0=len 'a'@0 'b'@1 'c'@2 'd'@3 'e'@4
- last_pos_of_c >= pos_substring_1st 0=last_pos_of_c 0=pos_substring_1st 5=pos=abc 5=len 'a'@5 'b'@1 'c'@2 'd'@3 'e'@4
- 5=len longest substring in string abcdeabc
- searching string: Iamhappy of length 8
- last_pos_of_c < pos_substring_1st -1=last_pos_of_c 0=pos_substring_1st 0=pos=Iamhappy 0=len 'I'@0
- last_pos_of_c < pos_substring_1st -1=last_pos_of_c 0=pos_substring_1st 1=pos=amhappy 0=len 'I'@0 'a'@1
- last_pos_of_c < pos_substring_1st -1=last_pos_of_c 0=pos_substring_1st 2=pos=mhappy 0=len 'I'@0 'a'@1 'm'@2
- last_pos_of_c < pos_substring_1st -1=last_pos_of_c 0=pos_substring_1st 3=pos=happy 0=len 'I'@0 'a'@1 'h'@3 'm'@2
- last_pos_of_c >= pos_substring_1st 1=last_pos_of_c 0=pos_substring_1st 4=pos=appy 4=len 'I'@0 'a'@4 'h'@3 'm'@2
- 4=len longest substring in string Iamhappy
- 16=total for 1 calls to lengthOfLongestSubstringViaIntsV2() with strings "abcabcbb", "bbbbb", "pwwkew", "abcdeabc", and "Iamhappy" in 0.000076 seconds
$ gcc -DDEBUG=0 -O1 -o length-of-longest-substring length-of-longest-substring.c && ./length-of-longest-substring
- 16000000=total for 1000000 calls to lengthOfLongestSubstringViaPtrs() with strings "abcabcbb", "bbbbb", "pwwkew", "abcdeabc", and "Iamhappy" in 0.117937 seconds
- 16000000=total for 1000000 calls to lengthOfLongestSubstringViaInts() with strings "abcabcbb", "bbbbb", "pwwkew", "abcdeabc", and "Iamhappy" in 0.110769 seconds
- 16000000=total for 1000000 calls to lengthOfLongestSubstringViaIntsV2() with strings "abcabcbb", "bbbbb", "pwwkew", "abcdeabc", and "Iamhappy" in 0.105714 seconds
- Both the pointer version source code and debug output are more difficult to understand.
- Both the array index version source code and debug output are easier difficult to understand.
- The array index version debug output contains more useful debug info which was also easier to write due to no pointers.
- Note: assert()s left out but they would also be easier to write due to no pointers.
- The array index versions run-time is as fast as the pointer version, and maybe even a little faster.