【问题标题】:Elementary C++ Type Confusion初级 C++ 类型混淆
【发布时间】:2010-02-25 02:27:07
【问题描述】:

我在看the following text from Stanford's Programming Paradigms class,注意到作者在使用string类的时候,构造函数做了一个类似这样的函数调用:

string::string(const char* str) {
    initializeFrom(str, str + strlen(str));
}

如果 initializeFrom 函数接受两个 char* 参数,那么第二个参数为什么可以将 (char* + int) 传递给 char* 并使其正常工作?类型系统如何解释这个语句?

提前致谢。

【问题讨论】:

  • strlen() 实际上返回 size_t,而不是 int。一个重要的区别是size_t 是无符号类型,即它只能保存正数。这是有道理的 - 字符串长度可以是 0、1 或 30000 个字符,但不能是 -7。

标签: c++ types constructor


【解决方案1】:

这就是所谓的指针运算。 char* + int 会导致 char* 在内存中比 int 字符高。

【讨论】:

  • 如果int 是-ve,它的内存也可能更低;所以它应该是unsigned int,结果在内存中总是更高。 [对不起,如果这是吹毛求疵;]
  • @legends2k 确实如此,虽然 strlen() 永远不应该返回负值,所以这里分析的特定代码将导致第二个参数总是大于或等于第一个。跨度>
  • strlen() 永远不会返回负数。它根本做不到;它返回一个 size_t,这是一个无符号类型。
【解决方案2】:

二元加法运算符+- 可以在一个参数是指向任何完整类型的指针(例如T* p)而另一个参数是整数(例如i)时使用。他们实现了所谓的指针算法

编译器假定指针指向某个数组的元素(例如,T array[N])。该操作生成一个指向数组另一个元素的指针,该元素与原始元素相距i 个元素。可以沿任一方向“移动”指针,即朝向数组的开头或朝向数组的末尾。例如,如果p 指向array[3],那么p + 4 将指向array[7]

该操作仅在结果指向数组的现有元素或数组的最后一个元素之后才有效,即给定数组T array[N],可以创建指向从array[0]到元素的指针虚元素array[N]。使用指针算术跨越这些界限的任何尝试都会导致未定义的行为。

T 类型必须是完整的,这意味着指针运算不能与 void * 指针一起使用,例如,即使某些编译器允许将其作为扩展(将 void * 指针视为等同于 @987654337 @指针)。

除二元加法运算符外,指针运算还包括前缀和后缀一元运算符++--(应用于指针)以及复合赋值运算符+=-=(在其上带有指针)左侧和右侧的整数)。

在您的情况下,str + strlen(str) 表达式将产生一个 char * 类型的指针,该指针指向字符串 str 中的终止 \0 字符。

【讨论】:

    【解决方案3】:

    请记住,指针只是一个保存内存地址的变量。因此,您可以将值添加到内存地址。内存地址是一个数字。

    当你给某个类型的指针加1时,它实际上会加1 * sizeof(type)。当你添加任何值 N 时,它实际上会添加 N * sizeof(type)。

    考虑以下示例:

    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.
    

    【讨论】:

      【解决方案4】:

      为什么第二个参数可以传递一个 (char* + int)

      它仍在传递一个指向strlen(str)char *,越过最初指向的位置。

      【讨论】:

        【解决方案5】:

        第一个参数指向 char 数组的开头,第二个参数指向 char 数组末尾的 NULL 字符。

        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
        

        【讨论】:

          【解决方案6】:

          我认为这可能被过度回答了。

          在:

           initializeFrom(str, str + strlen(str));
          

          str 是指向字符串开头的指针。

          (str + strlen(str)) 是指向字符串结尾的指针。

          请记住,str(字符指针)只是一个整数((int)(long)(long long),具体取决于架构),用于标识内存中的位置。

          【讨论】:

          • 指针不是(总是)整数。例如,在 x86-16 上,它是一对整数。
          猜你喜欢
          • 1970-01-01
          • 2017-08-14
          • 1970-01-01
          • 1970-01-01
          • 2011-11-04
          • 1970-01-01
          • 2017-12-24
          • 2013-12-31
          • 1970-01-01
          相关资源
          最近更新 更多