EXPLANATION
This is because, in C, an array declaration decays to a pointer internally (Refer to the citation at the end for details). When you declare char a[]
, it is the same as declaring char* a
. In both of these cases, a
stores the memory address of the first element of the array. But, in the case of variables like plain integers or characters, such as int x = 10;
, the variable x
will actually store the value 10
.
When you declare an array such as
char a[10];
the object designated by the expression a
is an array (i.e., a contiguous block of memory large enough to hold 10 character values a.k.a string), and the type of the expression a
is an "array of 10 character elements", or char[10]
. The expression a
is implicitly converted to char *
, and its value is the address of the first element.
Thus, when you pass an array variable to a function, you are actually passing the memory address (or base address) of the array. And since you have written your function declaration as:
void split(char take1[],char take2[], char str[])
It is the same as writing:
void split(char *take1,char *take2, char *str)
And, in your function call which is:
split(taker1,taker2,str);
taker1
, taker2
and str
actually contain base addresses of the respective character arrays (i.e. string). So you don't explicitly have to mention the address_of operator (&
) along with the array variables in the function call.
The code you have posted can also be written as follows:
void split(char *take1,char *take2, char *str){
int i=0,j=0,yes=0;
while(*(str+i) != '\0'){
if(*(str+i) == '*'){
yes=1;
i++;
}
if(yes==0){
*(take1+i) = *(str+i);
}
else if (yes!=0){
*(take2+i) = *(str+i);
j++;
}
i++;
}
}
int main(){
char taker1[30], taker2[30];
char str[30] = "Hello*world";
split(taker1, taker2, str);
printf("%s\n%s\n", taker1, taker2) ;
return 0;
}
Notice the interchanged array operator([]
) and and dereference operator(*
). Hint: Writing arr[5]
is the same as *(arr + 5)
.
LONG STORY SHORT:
- In C, arrays are passed by reference. Normal variables are passed by value.
- Array variables can be treated as pointers.
- You ought to normally skip the
&
with array variables in function calls.
BONUS
The aforementioned reason is also why we don't use &
in scanf()
for string variables (with %s
format specifier), i.e.,
char str[10];
scanf("%s", str);
But in the case of integers or other primaries:
int num;
scanf("%d", &num);
Also, you will get a better understanding of the concepts involved after going through dynamic memory allocation in C.
CITATION
Here's the exact language from the C standard (n1256):
6.3.2.1 Lvalues, arrays, and function designators ... 3 Except when it is the operand of the sizeof operator or the unary & operator or is a
string literal used to initialize an array, an expression that has
type ‘‘array of type’’ is converted to an expression with type
‘‘pointer to type’’ that points to the initial element of the array
object and is not an lvalue. If the array object has register storage
class, the behavior is undefined.