Reputation: 21
// Capitalizes a copy of a string while checking for errors
#include <cs50.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
// Get a string
char *s = get_string("s: "); //this is in the cs50.h
char *t = malloc((strlen(s) + 1) * sizeof(char));
// Copy string into memory
for (int i = 0, n = strlen(s); i <= n; i++)
t[i] = s[i];
return 0;
}
The above code is from cs50 2018 lecture #3 . t[i] = s[i]
part confused me. As I know, when we say char *t
, t
will store the address of the first part of the memory that was allocated. So doesn't t[i]
give us the address of the memory at t[i]
location ? If it is like so, shouldn't we write
*t[i] = s[i]
to change the value of t[i]
?
Upvotes: 0
Views: 76
Reputation: 17258
No, the []
array index operator dereferences the pointer and evaluates to the value itself, not its address. The expression s[i]
is equivalent to the expression *(s + i)
. If you wanted the address of the element at index i
, you would need to use the &
operator, as in &s[i]
(which is equivalent to s + i
).
int array[] = { 10, 20, 30, 40 }; // create an array for illustration
int *ptr = array; // array type decays to a pointer
// these print the same thing: the address of the array element at index 2
printf("%p\n", ptr + 2); // pointer arithmetic
printf("%p\n", &ptr[2]); // array index operator followed by address-of operator
// these print the same thing: the element at index 2 (= 30)
printf("%d\n", *(ptr + 2)); // pointer arithmetic followed by dereference operator
printf("%d\n", ptr[2]); // array index operator
Upvotes: 4
Reputation: 263517
char *s = ...;
char *t = ...;
...
t[i] = s[i];
t[i]
is an lvalue, an expression that refers to an object. Oversimplifying a bit [*], if it appears on the left side of an assignment (as it does here), it refers to a particular char
object, and the assignment updates the value of that object. s[i]
is similar, but it appears on the right side of the assignment, so it yields the value of the object.
It's essentially the same thing as:
int x;
int y;
y = x;
x
and y
are both names of objects, and they're both lvalues. The y
on the left hand side refers to the object. The x
on the right hand side yields the value stored in the object.
[*] The oversimplification is that there are contexts other than the left hand side of an assignment in which an lvalue refers to an object rather than yielding its value.
There's a bit more going on here in the way the []
operator is defined (see the comp.lang.c FAQ) section 6 for the relationship between arrays and pointers), but in this case all you really need to know is that s[i]
and t[i]
are the names of objects.
The gory details are in the C standard, N1570 draft, section 6.3.2.1.
Upvotes: 0
Reputation: 224437
t[i]
actually gives you the i
th element of the array. It works the same as s[i]
, which has the same type.
The syntax t[i]
is exactly the same as *(t + i)
. In other words, pointer arithmetic is performed to get a pointer to the desired element, then the result is dereferenced to get the actual element.
Upvotes: 2