指针或地址?

时间:2018-11-06 19:51:26

标签: c pointers cs50

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

上面的代码来自cs50 2018讲座#3。 t[i] = s[i]部分使我感到困惑。据我所知,当我们说char *t时,t将存储已分配内存的第一部分的地址。 t[i]不会给我们t[i]位置的内存地址吗?如果是这样,我们不应该写
*t[i] = s[i]更改t[i]的值?

3 个答案:

答案 0 :(得分:4)

否,[]数组索引运算符取消引用指针,并求值到值本身,而不是它的地址。表达式s[i]等效于表达式*(s + i)。如果您想要元素在索引i的地址,则需要使用&运算符,如&s[i](相当于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

答案 1 :(得分:2)

t[i]实际上为您提供了数组的第i个元素。它与s[i](具有相同的类型)相同。

语法t[i]*(t + i)完全相同。换句话说,执行指针算术以获取指向所需元素的指针,然后将结果取消引用以获取实际元素。

答案 2 :(得分:0)

char *s = ...;
char *t = ...;
...
t[i] = s[i];

t[i] lvalue ,它是引用对象的表达式。如果位[*]出现在分配的左侧(如此处所做的那样),则将其过度简化,它引用的是特定的char对象,并且分配会更新该对象的值。 s[i]与之类似,但是它出现在赋值的右侧,因此产生对象的 value

基本上与以下内容相同:

int x;
int y;
y = x;

xy都是对象的名称,并且都是左值。左侧的y是指对象。右侧的x产生存储在对象中的值。

[*]过于简单化是,除了赋值的左手以外,还有其他上下文,其中左值引用对象而不是产生对象的值。

这里定义[]运算符的方式还有很多事情(有关数组和指针之间的关系,请参见第comp.lang.c FAQ节),但是在这种情况下,您真正​​需要的只是知道s[i]t[i]是对象的名称。

C标准N1570 draft的第6.3.2.1。节中有详细内容。