我正在阅读the following text from Stanford's Programming Paradigms class,我注意到当作者使用字符串类时,构造函数执行的函数调用如下所示:
string::string(const char* str) {
initializeFrom(str, str + strlen(str));
}
如果initializeFrom函数接受两个char *参数,那么为什么第二个参数可以将(char * + int)传递给char *并使其正常工作?类型系统如何解释这个陈述?
提前致谢。
答案 0 :(得分:11)
这称为指针算术。 char * + int导致char *在内存中更高的int字符。
答案 1 :(得分:4)
当一个参数是指向任何完整类型的指针(例如,+
)而另一个参数是整数(例如,{}时,可以使用二元加法运算符-
和T* p
{1}})。他们实现了所谓的指针算法。
编译器假定指针指向某个数组的元素(例如,i
)。该操作产生一个指向数组另一个元素的指针,该元素距离原始元素T array[N]
个元素。可以在任一方向上“移动”指针,即朝向阵列的开头或朝向阵列的末端。例如,如果i
指向p
,则array[3]
将指向p + 4
。
该操作仅在结果指向数组的现有元素或超出数组的最后一个元素时才有效,即给定数组array[7]
,可以创建指向{{{}的元素的指针。 1}}到虚构元素T array[N]
。任何使用指针算法跨越这些边界的尝试都会导致未定义的行为。
类型array[0]
必须完整,这意味着指针算术不能与array[N]
指针一起使用,例如,即使某些编译器允许将其作为扩展(处理T
指针等同于void *
指针。)
除了二元加法运算符之外,指针算法还包括前缀和后缀一元void *
和char *
运算符(应用于指针)以及复合赋值运算符++
和{{ 1}}(左侧有指针,右侧有整数)。
在您的情况下,--
表达式将生成+=
类型的指针,该指针指向字符串-=
中的终止str + strlen(str)
字符。
答案 2 :(得分:2)
请记住,指针只是一个包含内存地址的变量。因此,您可以将值添加到内存地址。内存地址是一个数字。
当您向某个类型的指针添加1时,它实际上会添加1 * sizeof(类型)。当你添加任何值N时,它实际上会添加N * sizeof(类型)。
考虑以下示例:
int x[5] = {0,1,2,3,4};
int *p = &(x[0]);//point to the first element
p = p + 1;//p now points to the second element.
答案 3 :(得分:0)
第一个参数指向char数组的开头,第二个参数指向char数组末尾的NULL char。
const char *str = "abc";
char *start = str; // start now points to the first char.
char *end = str + strlen(str); // end now points to the null char at the end.
您可以通过打印确认:
printf("%c %d",*start,*end); // will output: a 0
答案 4 :(得分:0)
为什么第二个参数可以传递一个(char * + int)
它仍在通过char *
指向strlen(str)
超过最初指向的位置。
答案 5 :(得分:0)
我认为这可能是过度回答。
在:
initializeFrom(str, str + strlen(str));
str
是指向字符串开头的指针。
(str + strlen(str))
是指向字符串结尾的指针。
请记住,str
(字符指针)只是一个整数((int)
,(long)
,(long long)
,具体取决于架构),用于标识内存中的位置。