关闭

C++进阶之浅谈typedef

标签: C++
91人阅读 评论(0) 收藏 举报
分类:

背景

一直以来,对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

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:5455次
    • 积分:192
    • 等级:
    • 排名:千里之外
    • 原创:14篇
    • 转载:1篇
    • 译文:0篇
    • 评论:0条