arrays - 我需要帮助理解 "pointer to array of n integers"初始化的正确用法

标签 arrays c pointers implicit-conversion

以下声明:

<强> int (*x)[10]

定义为x是一个指向10个元素的整数数组的整数指针

问题 1:这是否意味着 x 最初指向 10 个整数数组的第一个元素?如果是这样,那么这与简单的 int x[10] 有什么不同?

问题 2:如果 int (*x)[10] 是不同的,那么它有什么不同以及它的实际用法有哪些实例?

问题3:我试图编写一个简单的程序访问、写入和打印数组元素。

#include <stdio.h>

void main()
{
    int (*x)[12], i;
    for(i = 0; i <= 11;)
    {
        (*x)[i] = i;
        printf("%d\n", (*x)[i++]);
    }
}

当我运行它时,我总是遇到段错误。据我了解,当我尝试访问我无权访问的内存时,会发生段错误。但我只访问已初始化的 12 个元素。那么为什么我的程序会因段错误而退出呢?另外,我是否正确访问了数组( (*x)[i] = i )?还有其他方法可以访问它吗?

最佳答案

对于根据 C 标准的初学者,不带参数的 main 函数应像这样标记

int main( void )

在所示的程序中,您声明了一个未初始化的指针

int (*x)[12], i;

具有不确定的值。因此取消引用指针

(*x)[i] = i;

导致未定义的行为。

相反,你可以写例如

#include <stdio.h>

int main( void )
{
    enum { N = 12 };
    int a[N];

    int (*x)[N] = &a;

    for ( size_t i = 0; i < N; i++ )
    {
        (*x)[i] = i;
        printf( "%d\n", (*x)[i] );
    }
}

虽然这样写程序看起来会更简单

#include <stdio.h>

int main( void )
{
    enum { N = 12 };
    int a[N];

    int *x = a;

    for ( size_t i = 0; i < N; i++ )
    {
        x[i] = i;
        printf( "%d\n", x[i] );
    }
}

在此声明中

int *x = a;

隐式转换为指向 int * 类型的第一个元素的指针。

在此声明中

int (*x)[N] = &a;

初始化表达式&a已经是int ( * )[N]类型的指针。

所以在表达式中

(*x)[i] = i;

子表达式*x 产生数组a 的左值。所以实际上上面的表达式等价于

a[i] = i;

注意两个声明中的内容

int *x = a;

int ( *x )[N] = &a;

指针x存储数组a占用的内存区的起始地址,但有不同的类型。取消引用第一个指针,您将获得数组 a 的第一个元素。取消引用第二个指针,您将获得整个数组本身。

关于arrays - 我需要帮助理解 "pointer to array of n integers"初始化的正确用法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72898582/

相关文章:

ruby - 具有范围值的数组?

arrays - 检查值是否在数组中作为字典值?

C - 拆分字符串

c - 非规范(原始)模式下的异步串行通信并在 linux/osx 中生成 SIGIO

pointers - 声明一个指向结构的指针

c++ - 使用指针逐列遍历多维数组

javascript - lodash takeRightWhile 从起始索引开始

javascript - 文本区域过滤数组Javascript

c - 如何获得有关 SIGFPE 信号的更多信息?

c - 为什么这个堆栈程序在使用 POP 时给出垃圾值?