C ++指向char算术的指针

时间:2013-06-07 01:57:01

标签: c++ arrays pointers

如果我向指针添加1,实际添加的值将是指针指向右侧的类型的大小?例如:

int* num[5];
cout << *num << ", " << *(num + 2) << endl; 

这将打印存储在num [1]和num [2]处的值, 所以如果我没错的话,num + 2实际上是num + 2 * sizeof(int)。

现在,如果我将一个指向char的指针数组初始化为字符串文字,就像这样:

char* ch[5] = 
{
     "Hi",
     "There",
     "I,m a string literal"
};

这可以做到,因为像“hi”这样的字符串文字表示其第一个字符的地址,在本例中为“h”。现在我的问题是如何写出类似的东西:

cout << *(ch + 2);

得到“我,一个字符串文字”作为输出? 既然指针指向char,那么实际上不应该向指针添加2(ch + 2 * sizeof(char))?给我输出'那里'?

它与cout有关吗? cout是否会搜索指向值的内存,以查看它是否发现'\ 0'将指向的值的内容识别为字符串,然后修改指针算术?但是,在指向字符串的char的指针中添加1意味着每次都会添加不同数量的字节(而不是char的大小),因为字符串可以是任何大小。或者我完全错了?对不起,我是C ++的新手,也是gerenal的编程。

4 个答案:

答案 0 :(得分:4)

数组不存储char,它存储char * s。因此,ch + 2将等同于ch + 2*sizeof(char *)。然后取消引用,指向"I'm a string literal"

您的初步示例显示了混淆:

int* num[5];
cout << *num << ", " << *(num + 2) << endl; 

这是一个指向int的指针数组。因此,*(num + 2)将是*(num + 2*sizeof(int *))不是 2*sizeof(int)。让我们用一个小程序演示这个:

#include <iostream>

int main()
{
    int *num[3];
    int x, y, z;
    x = 1;
    y = 2;
    z = 3;

    num[0] = &x;
    num[1] = &y;
    num[2] = &z;

    std::cout << *(num + 2) << "\n";
}

这将打印出一个内存地址(如0x22ff28),因为它持有指针,而不是值。

在C和C ++中,数组和指针非常相似(很多书都声称它们完全相同。这不是-quite-true,但在很多情况下都是如此)。

你的第一个例子应该是int num[5]。然后*(num + 2)(相当于num[2])将等同于*(num + 2*sizeof(int)。希望这会让你有些困惑。

答案 1 :(得分:2)

“如果我向指针添加1,实际添加的值将是指针指向右侧的类型的大小?”

在C ++标准中,无法保证指针是指针所指向的某个内存的字节数。如果向指针添加整数n,则结果是指向该数组中n下一个元素的指针:

int iarr[10];
int* pi = iarr;  // pi points to iarr[0]
int* pi2 = pi+2; // pi2 points to iarr[2]

你看到的是什么,例如{+ 1}}未由C ++标准定义。

最受欢迎的平台/实施将会发生什么?

int repr = (int)pi;

当你有指针数组时,会发生同样的事情:

(int)pi2 == ((int)pi) + 2*sizeof(int)

请注意,int* piarr[10]; int** ppi = piarr; // ppi points to iarr[0] int** ppi2 = piarr+2; // ppi2 points to iarr[2] 的类型是数组10 指向int 的指针,因此该数组的元素具有输入指向int 的指针。因此,指向该数组元素的指针具有类型指向 指向int 的指针。


piarr是一个包含char* ch[5] 的5个指针的数组。

char等是(窄)字符串文字。 (窄)字符串文字是n const "Hello" 数组,其中 n 是字符串的长度加1(用于终止{{1} }字符)。数组可以隐式转换为指向数组第一个元素的指针,这就是这里发生的事情:

char

数组\0包含三个指向char 的指针。这些是通过将数组转换为指针获得的,它们中的每一个都指向 数组的第一个元素:指针char* ch[5] = { "Hi", "There", "I,m a string literal" }; (数组{{1}的第一个元素})指向数组“Hi”的第一个元素,ch指向“There”的第一个元素,依此类推。

请注意,还有从ch[0]ch的转换,这种转换已弃用,应予以避免。更好的形式是:

ch[1]

表达式const char解释如下:

  • char命名该数组(见上文)
  • char const* ch[5] = { "Hi", "There", "I,m a string literal" }; 隐式地将*(ch + 2) 3个指针的数组转换为char 转换为指向指向char 的指针,指针指向第一个元素数组ch。因此,该表达式的类型是指向char 的指针的指针。
  • ch + 2使指针从最后一步指向第二个下一个元素;它指向ch的第一个元素,因此它现在指向数组ch的第三个元素。
  • ch + 2最后,ch取消引用指针并“抓取”指向的对象。由ch创建的指针指向数组*(ch + 2)的第3个元素,因此,此表达式解析为数组*的第3个元素。表达式的类型现在是指向char的指针

表达式的结果传递给ch + 2。由于表达式的类型是指向char 的指针,ch将打印该字符串:数组ch的第三个元素。

答案 2 :(得分:1)

  

是否与cout有关?

没有

const char* cstrings[5] = 
{
    "Hi",
    "There",
    "I,m a string literal"
};

const char** x = cstrings + 2;
cout << *x << endl;

但令人困惑的是&lt;&lt;当给定指向cstring的指针时,运算符的工作方式不同 - 它不输出地址,而是输出字符串。这是一个例子:

int x = 10;
int* pint = &x;

const char* pstr = "hello";

cout << pint << endl << pstr << endl;

--output:--
0x7fff5fbff85c  //hexidecimal string representation of an integer
hello
  

由于指针指向char,

1)文字字符串作为指针存储在数组中。这就是为什么数组的类型是指针。

2)指针是内存中的地址,只是整数。

3)所以你的指针数组实际上是一个整数数组。

答案 3 :(得分:1)

在C中,字符由数据类型char表示。它可以包含任何ASCII字符,范围从0到255.此外,它使用单个字节的大小。

然而,字符串由char*表示,其在技术上是一组字符。有区别。 charchar*不同。前者存储单个字符,后者存储与字符串偏移相对应的内存方向。

现在,在您的示例中,ch不是char*,而是char**。也就是说,它是一个字符数组的数组,或者说更好的是一个字符串数组。如果我们取消引用ch一次,就像在*ch中一样,我们将获得第一个字符串:Hi。如果我们取消引用它两次,如**ch,我们将得到第一个字符串的第一个字符:H。所以,我们可以开始使用指针算术!

cout << *(ch + 2)将输出I,m a string literal

cout << **(ch + 1)将输出T(第二个字符串的第一个字符)

cout << *(*ch + 1)将输出i(第一个字符串的第二个字符)

继续使用这些示例以更好地了解字符和字符串的输出方式!这都是关于指针算术的!