typeof()关键字

前言:

    typeof关键字是C语言中的一个新扩展,这个特性在linux内核中应用非常广泛。

一,说明
    typeof的参数可以是两种形式:表达式或类型。

    1,表达式的的例子:
        typeof(x[0](1)
        这里假设x是一个函数指针数组,这样就可以得到这个函数返回值的类型了。
        如果将typeof用于表达式,则该表达式不会执行。只会得到该表达式的类型。
        以下示例声明了int类型的var变量,因为表达式foo()是int类型的。由于表达式不会被执行,所以不会调用foo函数。
            extern int foo();
            typeof(foo()) var;

    2,参数的例子:
        typeof(int *) a,b;
            等价于:
            int *a,*b;


二,实例
    1,把y定义成x指向的数据类型:
           typeof(*x) y;
    2,把y定义成x指向数据类型的数组:
           typeof(*x) y[4];
    3,把y定义成一个字符指针数组:
            typeof(typeof(char *)[4] y;
    这与下面的定义等价:
            char *y[4];

    4,typeof(int *) p1,p2; /* Declares two int pointers p1, p2 */
            int *p1, *p2;

    5,typeof(int) *p3,p4;/* Declares int pointer p3 and int p4 */
            int *p3, p4;

    6,typeof(int [10]) a1, a2;/* Declares two arrays of integers */

            int a1[10], a2[10];

    7,定义一个宏返回一个最大值,为避免因为重复调用同一个变量,可以这样     

       把     MAX(x,y)  ((x)>(y)?(x):(y))

       改成   MAX(x,y)   ({   typeof(x) _x=x;\

                typeof(x) _y=y;\

                _x>_y?_x:_y;\ })



三,局限
    typeof构造中的类型名不能包含存储类说明符,如extern或static。不过允许包含类型限定符,如const或volatile。
    例如,下列代码是无效的,因为它在typeof构造中声明了extern:
        typeof(extern int) a;

四、举例

1、不用知道函数返回什么类型,可以使用typeof()定义一个用于接收该函数返回值的变量  

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

struct apple{
    int weight;
    int color;
};

struct apple *get_apple_info()
{
    struct apple *a1;
    a1 = malloc(sizeof(struct apple));
    if(a1 == NULL)
    {
        printf("malloc error.\n");
        return;
    }

    a1->weight = 2;
    a1->color = 1;

    return a1;
}

int main(int argc, char *argv[])
{
    typeof(get_apple_info()) r1;//定义一个变量r1,用于接收函数get_apple_info()返回的值,由于该函数返回的类型是:struct apple *,所以变量r1也是该类型。注意,函数不会执行。

    r1 = get_apple_info();

    printf("apple weight:%d\n", r1->weight);
    printf("apple color:%d\n", r1->color);

    return 0;
}

2、

在宏定义中动态获取相关结构体成员的类型

如下代码,定义一个和变量x相同类型的临时变量_max1,定义一个和变量y相同类型的临时变量_max2,再判断两者类型是否一致,不一致给出一个警告,最后比较两者。

#define max(x, y) ({                \
    typeof(x) _max1 = (x);          \
    typeof(y) _max2 = (y);          \
    (void) (&_max1 == &_max2);      \//如果调用者传参时,两者类型不一致,在编译时就会发出警告。
    _max1 > _max2 ? _max1 : _max2; })

3、

	//其它用法1
	char *p1;
    typeof (*p1) ch = 'a'; //ch为char类型,不是char *类型。
    printf("%d, %c\n", sizeof(ch), ch);//1, a

	//其它用法2
	char *p2;
    typeof (p2) p = "hello world";//此时的p才是char *类型,由于在64位机器上,所以指针大小为8字节
    printf("%d, %s\n", sizeof(p), p);//8, hello world


参考  https://gcc.gnu.org/onlinedocs/gcc-4.6.2/gcc/C-Extensions.html#C-Extensions

发布了407 篇原创文章 · 获赞 150 · 访问量 38万+

猜你喜欢

转载自blog.csdn.net/ds1130071727/article/details/102922365