Reputation: 329
I am practicing with pointers trying to familiarize myself with the ins and outs of pointers in the c-language. I have searched around the tutorials and haven't found a straight forward answer to my inquiry. Here is some code I've pieced together that demonstrates my issue. This simply sets a char pointer *s1
to a long string and a pointer s2
to a two letter string. The nested loop iterates through the long string looking for matches to the short string. However, I don't understand the information stored in the pointer. If I use the % Format %d
, the pointer gives me an integer, if I use %c
I get the letter I want. However, the line with if (*(s1+j)!=*(s2+k))
seems to rely on the pointer being an integer and adding to it for comparison. My understanding is that the pointer just points to a memory address where this string can be found. If I add a number to the memory address, how does it move through the string? Wouldn't it point to a new memory address? Here is the code I'm working with:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char* argv[]) {
int count, total;
int n1,n2,i,j,k;
char *s1 = "vrrecgcrer";
char *s2 = "re";
n1=strlen(s1)-1;
n2=strlen(s2);
printf("n1: %d, n2: %d\n",n1,n2);
for (i = 0; i <= (n1-n2); i++){
count=0;
for(j = i,k = 0; k < n2; j++,k++){
printf("j is %d -- k is %d -- 1st %c -- 2nd %d\n", j, k, *(s1+j), *(s2+k));
if (*(s1+j)!=*(s2+k)){
break;
}
else
count++;
if(count==n2)
{
total++;
}
}
}
printf("The number of substrings is: %d\n", total);
return 0;
} /* MAIN */
Upvotes: 2
Views: 188
Reputation: 310910
The expression in this if statement
if (*(s1+j)!=*(s2+k)){
is equivalent to
if ( s1[j] != s2[k] ){
So here there are compared two objects of the type char
that are implicitly converted to the type int
due to the integer promotion rules applied to the operands when the operator !=
is used.
From the C Standard (6.5.2.1 Array subscripting)
2 A postfix expression followed by an expression in square brackets [] is a subscripted designation of an element of an array object. The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2))). Because of the conversion rules that apply to the binary + operator, if E1 is an array object (equivalently, a pointer to the initial element of an array object) and E2 is an integer, E1[E2] designates the E2-th element of E1 (counting from zero).
In this statement
printf("j is %d -- k is %d -- 1st %c -- 2nd %d\n", j, k, *(s1+j), *(s2+k));
^^^
the expression *(s2+k)
that has the type char
is converted to the type int
due to the default argument promotions.
From the C Standard (6.5.2.2 Function calls)
7 ... The ellipsis notation in a function prototype declarator causes argument type conversion to stop after the last declared parameter. The default argument promotions are performed on trailing arguments.
See the declaration of the function printf
int printf(const char * restrict format, ...);
^^^
As for your program in whole then it is incorrect.
For example the variable total
was not initialized.
The condition in this for loop
for (i = 0; i <= (n1-n2); i++){
is wrong. Let's assume that the two strings have equal sizes. In this case the loop will be executed never.
Upvotes: 4
Reputation: 233
Everything in C is an integer straight up. Every character is represented as an integer underneath the hood. C just knows, with the proper library, that when you use %c to show that number as a character.
Now for your issue with the following:
if(*(s1+j)!=*(s2+k))
A character is one byte. When you add a number to a pointer, such as s1+j, then you actually increment j*byteSizeofDataType. For example, to access the second r in "vrrecgcrer" you would write *(s1+2) because by default the pointer s1 points to the first character in the string. Increment by one moves the pointer one byte in memory which is where the first r is located. Increment again moves another byte which points at the second r, etc.
Strings are not a real datatype in C -- they are just arrays of characters.
Upvotes: 2
Reputation: 86
You talk of pointer arithmetic. char *s
is NOT a pointer to string per say, it's a pointer to the 1st character of that string. Adding a number to a pointer results in pointer to ANOTHER item of that type that resides immediately after the former (and, btw, subtraction works, too).
So s + 1
is a pointer to the 2nd character, s + k
is a pointer to the k+1-th character. *(s + k)
is then dereference of that pointer (i.e. the character itself).
Oh, and btw, s[k]
is (in C) just another syntax for *(s + k)
.
Upvotes: 0