int *arr[] 如何是指向 int 的指针数组,而 char *arr[] 是指向字符串的指针数组?

时间:2021-05-06 14:26:55

标签: arrays c string pointers

在 C

int *arr[]

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

char *arr[]

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

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

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

3 个答案:

答案 0 :(得分: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 系列函数仅适用于 char*。按照传统和约定,char* 是 C 字符串的定义方式。在不同的情况下很可能是 int*,甚至完全是其他情况,例如某些操作系统如何使用 UTF-16 而不是 8 位编码。

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

答案 1 :(得分:0)

不,编译器一般不会区分它们。

考虑声明

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 * 类型的此类函数不存在。< /p>

相应地,一些输出函数被专门设计为在其参数类型为 char * 时输出字符串,因为与元素类型为 '\0' 的数组不同,字符串具有标记值 int

答案 2 :(得分:0)

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

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

这意味着 type* vartype var[] 都可以是 type 的“数组”,但 type* name 也可以只是指向某些类型数据的普通旧指针type - 在没有上下文的情况下看它,你真的无法分辨。

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

char *arr[] 要么是一个由 char “数组”组成的数组,要么是指向单个 char 的指针

最后——C 编译器不关心你在语法上正确使用它们所提供的内容——你可以访问一个 int* 作为一个 不是 的数组并得到垃圾数据,但 C 编译器的职责不是告诉您不要这样做。

相关问题