ikadorus
ikadorus

Reputation: 21

Pointer or address?

// 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

Answers (3)

TypeIA
TypeIA

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

Keith Thompson
Keith Thompson

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

dbush
dbush

Reputation: 224437

t[i] actually gives you the ith 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

Related Questions