如果我向指针添加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的编程。
答案 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*
表示,其在技术上是一组字符。有区别。 char
与char*
不同。前者存储单个字符,后者存储与字符串偏移相对应的内存方向。
现在,在您的示例中,ch
不是char*
,而是char**
。也就是说,它是一个字符数组的数组,或者说更好的是一个字符串数组。如果我们取消引用ch
一次,就像在*ch
中一样,我们将获得第一个字符串:Hi
。如果我们取消引用它两次,如**ch
,我们将得到第一个字符串的第一个字符:H
。所以,我们可以开始使用指针算术!
cout << *(ch + 2)
将输出I,m a string literal
cout << **(ch + 1)
将输出T
(第二个字符串的第一个字符)
cout << *(*ch + 1)
将输出i
(第一个字符串的第二个字符)
继续使用这些示例以更好地了解字符和字符串的输出方式!这都是关于指针算术的!