C++进阶之浅谈typedef

背景

一直以来,对typedef的理解都很粗浅,用的倒是不亦乐乎。直到前阵子,看到这样一段代码

typedef char  MyArray[32];
....

int main()
{
    MyArray array = {0};
}

虽然能看懂这段代码,也知道是怎么回事,但对于上面的typedef语句的细节处理还是有一些困惑,索性就查了一下。原理其实很简单,但有些细节若理解不清晰,也容易犯错,所以特此记录一下。


关于typedef

关于typedef的用法以及与宏定义的区别,不是本文记录的重点,在此推荐两篇说的比较清晰的博客:



其实语言本身的原理很简单,关键是使用过程中的一些需要注意的小细节,能否驾驭得了细节,才是是否真正掌握原理的体现。



细节之处见真知

通过上面推荐的两篇博客,已经可以知道,通过使用typedef,所定义的已经不单单是某个表达式或者类型的别名,而是一个自定义的类型了,我们可以将它与int, double, char等归为一类,都是现在程序中,我们可以用来定义变量的某个类型。通过下面的例子,可以更好的理解上面的说明。(其实上面一句话,就是本文想说明的重点,对自己也对其他看到本博客的人)


#include <iostream>

using namespace std;

typedef char MyArray[32];

void show_par_sizeof(MyArray typedef_array, char* normal_array)
{
    printf("sizeof(typedef_array) = %d\n", sizeof(typedef_array));
    printf("sizeof(MyArray) = %d\n", sizeof(MyArray));
    printf("sizeof(normal_array) = %d\n", sizeof(normal_array));
}


int main() {
    MyArray test_typedef_array = {0};
    char test_normal_array[32] = {0};

    printf("sizeof(test_typedef_array) = %d\n", sizeof(test_typedef_array));
    printf("sizeof(MyArray) = %d\n", sizeof(MyArray));
    printf("sizeof(test_normal_array) = %d\n", sizeof(test_normal_array));

    show_par_sizeof(test_typedef_array, test_normal_array);

    return 0;
}


这段代码对应的输出为:




由输出,再结合上面的代码,有两个关键细节值得注意:

1、为什么sizeof(MyArray) = 32;
2、由代码可知test_typedef_array实际上是一个32位的字符型数组,在main中调用show_par_sizeof函数时是以test_typedef_array为参数的,为什么在show_par_sizeof函数定义时,第一个参数为MyArray typedef_array,按照之前对数组的理解,应该为指针类型才对呀;

关于第一个问题,这里要强调的就是上面说过的话,typedef定义的是一个可以和int, double类比的新类型,所谓类型,即是一个整体性的概念。这里MyArray就是被typedef定义成一个代表32字节的字符型数组的新类型,就像sizeof(int) = 4一样,这样就可以理解为啥sizeof(MyArray) = 32了。

关于第二个问题,就是一个比较扭曲的问题,所以我在程序中同时定义了一个正常的字符型数组作为对比。我得出的结论是,虽然从定义形式上区别很大,但MyArray到底层编译器解析时就是分配一个32字节的空间,然后将首地址与test_typedef_array绑定,与正常的字符数组并没有差别。因此,我们完全就可以把test_typedef_array当成是通过char test_typedef_array[32]定义的字符数组的数组名进行使用。而关于上面的问题,我的猜想是,当编译器进行编译时,会将show_par_sizeof函数定义中的MyArray typedef_array解析成char *typedef_array,这也就是为什么在show_par_sizeof函数中打印出来的信息,typedef_array和normal_array的大小是一样的,都是一个指针的大小(64位系统)。

为了验证上面的猜想,改了下程序:

#include <iostream>

using namespace std;

typedef char MyArray[32];

void show_par_sizeof(char* typedef_array, char* normal_array)
{
    printf("sizeof(typedef_array) = %d\n", sizeof(typedef_array));
    printf("sizeof(MyArray) = %d\n", sizeof(MyArray));
    printf("sizeof(normal_array) = %d\n", sizeof(normal_array));
}


int main() {
    MyArray test_typedef_array = {0};
    char test_normal_array[32] = {0};

    printf("sizeof(test_typedef_array) = %d\n", sizeof(test_typedef_array));
    printf("sizeof(MyArray) = %d\n", sizeof(MyArray));
    printf("sizeof(test_normal_array) = %d\n", sizeof(test_normal_array));

    show_par_sizeof(test_typedef_array, test_normal_array);

    return 0;
}


果然能够编译通过,运行结果为:



与之前的结果完全一样,因此验证猜想。


有了解底层编译原理的大神,希望能够在评论中,对第二个问题从编译器的角度进行下详细阐述,不胜感激。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值