【问题标题】:Pointer arrays confusion指针数组混淆
【发布时间】:2013-05-26 14:56:08
【问题描述】:

好的,根据我对指针数组的理解:

一个数组被认为是一个常量指针的等价物,因为它指向它的每个索引元素。指向数组的指针也等同于第一个索引的地址。

好吧 - 因为这是有效的:

int test[] = {1, 2, 3}

int * point = test;

cout << test + 2; //gives the address of the 3rd element test[2]

我想知道,这怎么会有不同的行为?

char arr[] = "testing pointer arrays";
char * pointer = arr;
cout << pointer + 3 << endl; //would output the actual string at pos arr[3]

类似地:

char * test = "zomg";
cout << test + 2; //outputs mg

在这种情况下 char 指针真的很特别吗?这给我带来了另一个关于流式传输函数的问题,您可以通过增加点并指定大小来指定可以写入/读取的字节数(例如 in ofstream::write(char pointer, size);) 此外,将结构类型转换为字符指针可以将其转换为字节数组吗?

任何澄清将不胜感激,谢谢。

【问题讨论】:

标签: c++ arrays pointers stream byte


【解决方案1】:

这个

char arr[] = "hello";

等价于

char arr[] = {'h', 'e', 'l', 'l', 'o', '\0'};

唯一的区别是字符串字面量的含义,例如"hello",而不是char 数组的处理方式。其他内置类型的那些。

接下来,当您将char* 传递给std::cout

std::cout << pointer + 3 << endl;

您会受益于 ostream&amp; operator&lt;&lt;char* 的特殊重载,它将指针视为空终止字符串的第一个元素。

【讨论】:

  • 那么,为什么不 - 在 char 数组的情况下 - 然后输出变量的地址 - 就像整数一样?
  • @AndyCarter 我为此添加了解释。
【解决方案2】:

发生这种情况是因为在 C 中(由于历史原因,在 C++ 中也是如此),在大多数情况下,指向 char 的指针被认为是指向以字符 NUL 终止的字符序列的指针(写为 '\0') .

因此,例如,如果您有一个接受 std::string 的 C++ 函数,您还可以传递一个指向 char 的指针,因为该语言假定您想要从 C 字符串进行隐式转换(即由 @987654324 终止的字符序列@) 和标准 C++ 字符串。

输出操作符的作用相同,因此在发送test+2 时,它假定您确实想从那里开始输出 C 字符串。

【讨论】:

  • +1 提及 C 字符串文字的历史 C 合规性规则
【解决方案3】:

它指向它的每个索引元素。

您忘记了有关数组的一些重要内容,它们是一种数据结构,可以在内存中的连续区域中分配,并且每条记录都包含相同类型的数据。考虑到数组的定义,您真正需要知道的唯一一件事是数组从哪里开始以及何时结束,您不需要指向数组中的每条记录,因为您可以确定它会在任何给定数组的开始和结束。

你的例子

int test[] = {1, 2, 3}

int * point = test;

cout << test + 2; //gives the address of the 3rd element test[2]

它只是向您展示了这一点,但对初学者来说以一种更神秘的方式。

test 是一个未指定大小的数组[],但它有一个有限的元素列表,因此编译器足够聪明,可以为test 分配一个空间,包含 3 个元素、3 个 int 和数组test 已创建。

int * point = test; 这里有指向数组第一个元素的测试,或者换句话说,数组开始的位置point 它是一个指向 int 的指针,以及一个地址这正是您可以提供给指针的内容,因此这里没有错误,但请记住,您在此处使用数组标签 test 传递数组的起始地址。

换句话说,test[0] 为您提供数组中第一个值的值,test 为您提供整个数组的地址。

test + 2 所以你知道test 只是一个地址的占位符,现在你只是简单地加 2,结果是你跳过了 2 个位置,你直接到第三个值的位置,但是总是根据内存中的地址,而不是存储的值。

最后一个操作是指针算术的一个例子,它基本上是一个用简单数字完成的逻辑操作,事实上,由于数组只是内存中的一个连续块,你可以计数 +1 或 -1 以达到下一个或上一个值,您的问题是数组没有真正的边界检查,因此您甚至可以向上或向下如此之多,以至于您到达属于其他东西的内存地址.

有一个关于指针运算

的简单例子
#include <stdio.h>

int main()
{
  int k[] = {34,765,23,5,7,123,8,99};
  int j = 3;

  printf("\nfirst print is  %d \n",k[j]);
  printf("\nsecond print is %d \n",j[k]);

  return(0);
}

这是您需要了解的关于指针运算的全部内容,请记住,没有自动边界检查,一切尽在您手中!

【讨论】:

    猜你喜欢
    • 2021-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-01
    相关资源
    最近更新 更多