文档章节

C语言的typedef理解

谁染霜林醉
 谁染霜林醉
发布于 2014/08/20 13:29
字数 1052
阅读 24
收藏 0

1.包含指针的用法

#include <stdio.h>  
typedef char* PCHAR;  
  
int main()  
{  
    PCHAR first_name = "first name";  
    PCHAR last_name = "last name";  
  
    printf("--%s-- \n",first_name);  
    printf("--%s-- \n",last_name);  
}

2.包含结构体的用法

typedef struct Student  
{  
    int age;  
    int id;  
    char* name;  
}STU;  
  
STU student;

或者:

struct Student  
{  
    int age;  
    int id;  
    char* name;  
};  
  
typedef struct Student student;

3.下面分析几个例子

3.1 有这样一个: char *  (*f[5]) (int,char*);

原则:左右法则,看括号

我们可以看出,主要是由2个括号组成的。第一个括号里是*f[5],第二个括号里是 int,char*。最前面还有一个char*.

 ---> 在*f[5]中,由于[]的优先级高于*,所以,他是一个数组,且是一个指针数组。加上外面的括号,我们可以得出,他是一个函数指针数组。

----> 那么,(int ,char*)就是每个函数的参数。


上面我们提到  【每个函数  】,因为函数指针数组里,每个元素都指向一个函数,对我们的声明来说,有5个参数是(int ,char*)的函数。

那么char* 就是他们的返回值。

所以我们知道,要重新起名的,是函数指针数组的名字,就是那个f。

所以我们用typedef来声明它的时候,需要这样作就好了:

typedef char* (*array_func[5])(int a,char* b);
//因为是声明,所以参数里的a,b不填也是可以的。
array_func functions;
//那么functions就有5个元素

当然,这是大家在网上都能看见的,但是这样是唯一的吗?答案是否的。

你可以

typedef char* (*array_func)(int a,char* b);

那么声明变量的时候,你就用

array_func functions[5];

效果是一样的,灵活对待。来看一下具体的应用。

#include <stdio.h>  
  
//char *(*real_func[5])(int,char*);  
  
char* get_info(int id,char* name);  
  
typedef char* (*array_func[5])(int a,char* b);   
  
array_func func;  
  
int main()  
{  
    func[0] = get_info;  
  
    printf("--%s--",func[0](1,"your name"));  
}  
  
  
char* get_info(int id,char* name)  
{  
    return name;  
}

代码是可以运行的,可以尝试一下。


如果写成

typedef char* (*array_func)(int a,char* b);  
array_func functions[5];

可能更好理解一些。仔细观察:

typedef char* (*array_func[5])(int a,char* b);

char* get_info(int id,char* name);

是一样的类型,所以能将get_info赋值给functions[0]。因为functions数组中每个元素都是get_info类型的函数指针。


3.2再来分析一个: void (*b) (void (*) ()) ;

老规矩,先看括号。左面括号里是 *b ,右面括号里是void(*)().最左面还有一个void

很明显啊,这就是一个函数指针,只不过参数复杂了点。

void(*)()!大家一看 ,很眼熟吗,这不又是一个函数指针吗,只不过忘记起名字而已。

我们稍微给他起个名字,

void (*b) (void (*c) ()) ;

那么是不是可以给他typedef了呢,先别急,这里面是不是有2个名字呢?对啊,那样编译器是不是会傻傻分不清呢?

这里姑且给他拆分成2段,实际上同时有函数指针和其他结构并存,我们一般要分步声明!!!

typedef现在就是起个新名字:

typedef void (*param)();
typedef void (*function)(param);

这样的好处大家一会就见到了。现在让我们看代码!

#include <stdio.h>  
  
//void (*b) (void (*) ()) ;  
  
typedef void (*param)();  
  
typedef void (*function)(param);  
  
  
void my_func(param p);//我们分步声明了,可以直接使用param来做参数  
void fff();  
  
int main()  
{  
    function f;  
    param p;  
  
    p = fff;  
    f = my_func;  
    f(p);  
}  
  
void my_func(param p)  
{  
    p();  
}  
  
void fff()  
{  
    printf("---- \n\n");  
}

可以运行一下代码。


3.3现在看最后一个: doube(*)()   (*e)[9]; 

 --->类似char x;的造型。

相信大家很快就看出来了啊, doube(*)() 是一个函数指针,(*e)[9]是一个数组指针,就是个指针! 步长是9. 这个指针的类型是 函数指针。有点绕。

那么按照我们上个例子的总结,要分开声明一下。

typedef double (*func)();
typedef func(*array)[9];

#include <stdio.h>  
#include <stdlib.h>  
  
//doube(*)()   (*e)[9];  
  
typedef double (*func)();  
typedef func(*array)[9];  
  
array func_array ;  
  
double get_number() ;  
  
int main()  
{  
    func_array = (array)malloc(sizeof(array));//切记,指针使用时要申请内存  
    (*func_array)[0] = get_number;  
    printf("%f \n\n\n",(*func_array)[0]());  
}  
  
double get_number()   
{  
    return 1000000;  
}

这段代码,大家看一下,就可以啦。

暂时到这。


© 著作权归作者所有

下一篇: C语言的结构体
谁染霜林醉
粉丝 3
博文 15
码字总数 18432
作品 0
济南
程序员
私信 提问
C语言学习之 数组,指针,字符串. (三)

保持一贯的风格, 进入正题之前,先写一段废话. 写点东西是件轻松的事, 我从未将写内容当作是一种负担. 但是生活中总有一些事情会扰乱心神. 我是说我之前想把一篇内容写全,写丰富完整事实上我写...

泡不烂的凉粉
2012/11/08
101
0
C语言基础-15-typedef

这讲介绍C语言中很常用的一个关键字---typedef。 一、typedef作用简介 * 我们可以使用typedef关键字为各种数据类型定义一个新名字(别名)。 #include <stdio.h> typedef int Integer;typedef...

Corwien
2016/03/16
16
0
uint8_t uint16_t uint32_t uint64_t

在nesc的代码中,你会看到很多你不认识的数据类型,比如uint8t等。咋一看,好像是个新的数据类型,不过C语言(nesc是C的扩展)里面好像没有这种数据类型啊!怎么又是u又是t的?很多人有这样的...

起始页
2013/12/31
0
0
复杂声明 | C语言

今天看了《C专家编程》里的'分析C语言的声明'一章,终于懂了C语言的复杂声明是怎么解析的。虽然在平时写代码的时候用到复杂声明的情况几乎没有,这里还是做一个记录,也是加深对C语言声明的理...

好好编程
2018/01/16
0
0
typedef struct与struct的区别 自学

第一篇:typedef struct与struct的区别 1. 基本解释 typedef为C语言的关键字,作用是为一种数据类型定义一个新名字。这里的数据类型包括内部数据类型(int,char等)和自定义的数据类型(str...

itJackChen
2011/08/11
346
1

没有更多内容

加载失败,请刷新页面

加载更多

Spring Boot + Mybatis + Ehcache 二级缓存实例

二级缓存是多个SqlSession共享的,其作用域是mapper的同一个namespace,不同的sqlSession两次执行相同namespace下的sql语句且向sql中传递参数也相同即最终执行相同的sql语句,第一次执行完毕...

xiaolyuh
1分钟前
0
0
Spring源码学习(二)哎呦,按菜谱做菜与AbstractAutowireCapableBeanFactory.createBean流程差不多

记得跟老婆谈恋爱时,有一天心血来潮给老婆做饭,按照菜谱一步一步的做,结果差点把厨房烧了!!! 这事至今老婆还记得。 入口 上一篇说了,AbstractBeanFactory.getBean的主流程 ,今天来说下...

温安适
3分钟前
6
0
前端UI攻城狮 你们该抛弃jQuery了

你不再需要jQuery! Web工程师太依赖jQuery了,某种意义上说jQuery已经成了JavaScript的同义词。但是我们真的需要他么?或许我们应该反思一下什么时候才真的需要jQuery。 对我个人而言开始使...

前端老手
5分钟前
0
0
六、Java设计模式之工厂方法

工厂方法定义: 定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类中进行 类型:创建型 工厂方法-使用场景: 创建对象需要大量重复的代码 ...

东风破2019
47分钟前
5
0
win服务器管理遇到的一系列问题记录

有些小伙伴在使用iis7远程桌面管理工具的时候总是会遇到一系列的问题,下面就是为大家介绍一下服务器日常管理过程中出现的问题及我的解决办法和心得。希望能帮到大家。   拒绝服务器重新启...

1717197346
54分钟前
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部