【问题标题】:how int *arr[] is array of pointers to int but char *arr[] is array of pointers to string?int *arr[] 如何是指向 int 的指针数组,但 char *arr[] 是指向字符串的指针数组?
【发布时间】:2021-07-28 21:19:28
【问题描述】:

在 C 中

int *arr[]

显然是一个指向 int 的指针数组,但用于

char *arr[]

是指向字符串的指针数组,这是怎么回事。那么编译器如何区分这两者。我读了这个问题-

Char* array of chars, but int* not array of ints?

但是对于指向字符串的指针数组,我们谈论的是编译器必须为字符串单独创建的大内存,然后编译器是否会以某种方式分别处理变量?

【问题讨论】:

  • char *arr[] 不必是指向字符串的指针数组,因为内容可能是 NULL 或指向非空终止数据的指针。它是一个指向char 的指针数组。
  • @MikeCAT 我不明白你所说的非空终止数据的意思。是的,它应该只创建指向 char 而不是字符串的指针数组
  • C 没有名为 string 的类型。字符串是一个字符数组。与任何数组一样,指向字符串的指针也是指向其第一个元素的指针。
  • 实际上,char **array[] 将是一个指向字符串的指针数组。 char *array[] 是一个字符串数组,因为正如其他人指出的那样,C 中的字符串只是 char*

标签: arrays c string pointers


【解决方案1】:

不,编译器通常不会区分它们。

考虑声明

int a[] = { 1, 2, 3 };
int * pa[] = { a, a + 1,  a + 2 };

char s[] = { '1', '2', '3' };
char * ps[] = { s, s + 1, s + 2 };

如您所见,没有主要区别。

这是一个演示程序。

#include <stdio.h>

int main(void) 
{
    int a[] = { 1, 2, 3 };
    int * pa[] = { a, a + 1,  a + 2 };
    
    for ( size_t i = 0; i < sizeof( pa ) / sizeof( *pa ); i++ )
    {
        printf( "%d ", *pa[i] );
    }
    putchar( '\n' );
    
    char s[] = { '1', '2', '3' };
    char * ps[] = { s, s + 1, s + 2 };

    for ( size_t i = 0; i < sizeof( ps ) / sizeof( *ps ); i++ )
    {
        printf( "%c ", *ps[i] );
    }
    putchar( '\n' );
    
    return 0;
}

程序输出是

1 2 3 
1 2 3 

唯一的区别是,标准声明的字符串函数需要 char * 类型的参数,该参数指向字符串的第一个元素,而对于 int * 类型,则不存在此类函数。

因此,一些输出函数专门设计用于在参数类型为 char * 时输出字符串,因为字符串的标记值 '\0' 与元素类型为 int 的数组不同。

【讨论】:

    【解决方案2】:

    int*char* 行为相同,只是后者被视为 C 字符串,而前者不是。 C 字符串只是指向char 的指针,如“一个或多个字符,具体取决于目标分配的内存大小”。

    int *arr[] // Array of pointers to (at least one) int
    char *arr[] // Array of pointers to (at least one) char (a.k.a. a "C string")
    

    编译器没有特别区分,但所有默认的str-family 函数仅适用于char*。按照传统和约定,char* 是 C 字符串的定义方式。在不同情况下很可能是int*,或者甚至完全是其他东西,例如某些操作系统如何使用 UTF-16 而不是 8 位编码。

    在这两种情况下,int* x[]char* y[] 的行为完全相同。

    【讨论】:

      【解决方案3】:

      C 中的“数组”本质上是指针的包装器——它们确实是 have differences,但为了这个问题,您可以将它们视为指向其中第一个元素的指针。

      其次,C中的指针数组可以下标——也就是说,您可以使用方括号([])对它们进行类似数组的访问。在底层,这只是一些用于获取所需元素的指针算法。

      这意味着type* vartype var[] 都可以是type 的“数组”,但type* name 也可以只是一个普通的旧指针,指向type 类型的某些数据——看它时不需要你无法真正说出的上下文。

      所以int *arr[] 要么是int“数组”的数组,要么是指向单个ints 的指针

      char *arr[]char“数组”的数组或指向单个chars 的指针

      最后 - C 编译器并不关心它们提供了什么,只要你在语法上正确使用它们 - 你可以访问一个 int* 作为一个数组,不是一个数组并获取垃圾数据但告诉你不要这样做不是 C 编译器的工作。

      【讨论】:

        猜你喜欢
        • 2017-09-03
        • 2021-02-07
        • 2010-11-25
        • 2013-07-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多