C中的指针索引是什么?它们引用什么?

C中的指针索引是什么?它们引用什么?,c,pointers,indexing,C,Pointers,Indexing,我已经搜索了一段时间,大多数结果都没有什么帮助,因为几乎所有与索引和指针相关的问题都指向数组。我在想象指针的索引可能是什么时遇到了一个概念上的问题。此示例函数从参数中获取argv[1]: unsigned long pointerfun(const char* p){ int* ip; // Declare an int pointer ip ip = (int*)p; // Initialize the poin

我已经搜索了一段时间,大多数结果都没有什么帮助,因为几乎所有与索引和指针相关的问题都指向数组。我在想象指针的索引可能是什么时遇到了一个概念上的问题。此示例函数从参数中获取
argv[1]

unsigned long pointerfun(const char* p){
    int* ip;                    // Declare an int pointer ip
    ip = (int*)p;               // Initialize the pointer with the value of p cast to an int pointer
    int i;
    int res=0;
    for(i=0; i<5; i++){         // Loops from 0 to 4
        res += ip[i];           // ...incrementing res by ip[0], ip[1],...
    }
    return res;
}
无符号长指针函数(const char*p){
int*ip;//声明一个int指针ip
ip=(int*)p;//使用p值初始化指针,并将其转换为int指针
int i;
int res=0;

对于(i=0;i
ip[n]
*(ip+n)
相同

您可以将
ip[n]
视为地址
ip
处的
integer
之外的第n个整数


另外,如果没有正确分配内存,可能会遇到一些运行时错误/调用未定义的行为。

ip[n]
*(ip+n)
相同

您可以将
ip[n]
视为地址
ip
处的
integer
之外的第n个整数


此外,如果没有正确分配内存,可能会遇到一些运行时错误/调用未定义的行为。

为了帮助您更好地理解,让我们尝试使其更“图形化”

内存是一系列可以存储值的连续位置。分配
ip=(int*)p
后,您可以像这样查看
ip

ip | v +-------+-------+-------+---- | ip[0] | ip[1] | ip[2] | ... +-------+-------+-------+---- ^ ^ ^ ^ | | | | 100 104 108 112 知识产权 | v +-------+-------+-------+---- |ip[0]| ip[1]| ip[2]|。。。 +-------+-------+-------+---- ^ ^ ^ ^ | | | | 100 104 108 112 由于
ip
是一个指针,它所指向的“数组”实际上没有特定的端点,您必须跟踪自己的端点


现在说到寻址,为了简单起见,让我们假设
ip
指向地址
100
,这意味着变量
ip
的内容是
100
。也可以说
sizeof(int)==4

然后,当您执行
ip[2]
时,这与执行
*(ip+2)
是一样的,然后您添加
2*sizeof(int)
(即
8
)作为指针的字节偏移量,并获取地址
108
,然后将其取消引用,给出
ip[2]
的内容(无论是什么)



现在让我们好奇一点,并“真的炒你的面条”:多亏了of,表达式
*(ip+i)
当然与
*(i+ip)
相同,这导致了一种奇怪但有效的转换,
ip[i]
i[ip]
为了帮助你更好地理解,让我们试着让它变得更有趣“图形化”

内存是一系列可以存储值的连续位置。分配
ip=(int*)p
后,您可以像这样查看
ip

ip | v +-------+-------+-------+---- | ip[0] | ip[1] | ip[2] | ... +-------+-------+-------+---- ^ ^ ^ ^ | | | | 100 104 108 112 知识产权 | v +-------+-------+-------+---- |ip[0]| ip[1]| ip[2]|。。。 +-------+-------+-------+---- ^ ^ ^ ^ | | | | 100 104 108 112 由于
ip
是一个指针,它所指向的“数组”实际上没有特定的端点,您必须跟踪自己的端点


现在说到寻址,为了简单起见,让我们假设
ip
指向地址
100
,这意味着变量
ip
的内容是
100
。也可以说
sizeof(int)==4

然后,当您执行
ip[2]
时,这与执行
*(ip+2)
是一样的,然后您添加
2*sizeof(int)
(即
8
)作为指针的字节偏移量,并获取地址
108
,然后将其取消引用,给出
ip[2]
的内容(无论是什么)



现在,让我们好奇一点,“真的炒你的面条”:多亏了of,表达式
*(ip+i)
当然与
*(i+ip)
相同,这导致了
ip[i]
i[ip]相同的奇怪但有效的转换

你应该将其视为未定义的行为,而不是使用它。除非你知道自己在做什么,如果你必须问,你不会。非常简单,你可以将
ip
视为
int
元素的数组。在许多情况下,数组和指针是可互换的。此外,对于任何数组或指针
p
和索引
i
表达式
p[i]
*(p+i)
是等价的。
ip[i]
-->
*(ip+i)
@mariusiuram Nope,就像我对任何数组或指针所说的那样。如果有
void*
,这将导致编译器错误。向指针(任何指针)添加一个数字将在基类型的大小中添加偏移量。例如,对于
int*
基类型为
int
因此
ip+2
将添加
2*sizeof(int)
作为字节偏移量。你应该将其视为未定义的行为,不要使用它。除非你知道你在做什么,如果你必须问,你不会。非常简单,你可以将
ip
视为
int
元素的数组。在许多情况下,数组和指针是可互换的。此外,对于任何数组或指针
p
索引
i
表达式
p[i]
*(p+i)
是等价的。
ip[i]
-->
*(ip+i)
@mariusiuram Nope,就像我对任何数组或指针所说的那样。如果有
void*
,这将导致编译器错误。向指针(任何指针)添加一个数字将在基类型的大小中添加偏移量。例如,对于
int*
来说,基类型是
int
因此
ip+2
2*sizeof(int)
添加为字节偏移量。您的意思是如果缓冲区没有