c - 在c中工作的运行时数据类型,sizeof如何工作?

标签 c pointers runtime

众所周知,我们可以使用int (*p)[10]来定义一个指向int[10]数组的指针,所以如果我们有p=0sizeof(int)==4p+1 将是 0+10*4 = 40,这是有效的,因为编译器在编译时知道 p 是什么。

如果我们这样做怎么办:

int main()
{
    int sz = 10;
    int (*p)[sz];
}

换句话说,在程序运行之前没有人知道sz。我认为这不应该起作用,但它确实起作用..

所以我的问题是,它是如何工作的?我的意思是,有没有地方可以在运行时在 c 中存储值的类型?如果不是,这怎么行得通?这只是与编译器相关吗?

我使用的是gcc版本4.4.5(Ubuntu/Linaro 4.4.4-14ubuntu5),您可以使用以下代码进行测试。

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main()
{
    int COL ;
    int ROW ;
    scanf("%d %d", &COL, &ROW);
    int (*p)[COL];
    int *mem = (int*)malloc(sizeof(int)*COL*ROW);
    memset(mem,0,sizeof(int)*COL*ROW);
    p = (int (*)[10])mem;

    printf("0x%p\n", p);
    printf("COL=%d\n", p+1, (((int)(p+1))-((int)p))/sizeof(int));

    mem[2*COL+0] = 1;
    printf("%d\n", p[2][0]);
    mem[2*COL+5] = 2;
    printf("%d\n", p[2][5]);
    mem[6*COL+7] = 3;
    printf("%d\n", p[6][7]);

    p[1][2] = 4;
    printf("%d\n", mem[1*COL+2]);

    free(p);

    return 0;
}

我希望我没有问一个愚蠢的问题,也没有犯愚蠢的错误......

最佳答案

可变长度数组类型的指针算术根据 6.5.6:10 进行了明确定义,其中的示例代码与您的非常相似。根据 6.5.3.4:2,当 sizeof 应用于可变长度数组时,会在运行时评估操作数以确定大小,因此可变长度数组指针算术同样进行。

自第二版(ISO/IEC 9899:1999 修订版)以来,可变长度数组 (6.7.6.2:4) 已成为标准的一部分;然而,它们是可选功能,一致性实现不必支持 (6.10.8.3)。

关于c - 在c中工作的运行时数据类型,sizeof如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12636774/

相关文章:

c++ - 如何使用cmake正确链接库?

ios - 我们如何在 iOS 设备运行时处理启用/禁用背景音频功能?

c# - 在运行时动态修改样式(添加触发器)

c - C语言中 'objects'是什么意思?

c++ - 静态变量会减慢应用程序的启动时间

c++ - 为链接列表建立条目类

c - 指针与 c 中的整数二维数组和字符串不同

java - 为什么这段 Scala 代码会在运行时抛出 IllegalAccessError?

c - 为什么地址 sanitizer 有时会忽略段错误?

c - 它们是否不同 : converting type of pointer then get data AND getting data of pointer then convert datatype