C语言中的声明--函数声明、指针函数、函数指针、typedef

   最近在看《程序员面试宝典》对于第6章指针和引用中的部分复杂一些的声明比较头痛,于是忍不住又翻了翻《C Primer Plus》第14章,做一下归纳:

   其实无外乎就是指针、数组、函数指针的各种组合。分析一个复杂些的声明和写一个复杂些的声明是一个正向和逆向的推导过程。
   分析一个声明,先要分层,先确定这个声明是个函数指针、指针、数组,再一层一层的剥开分析。
   而写一个声明,由于有文字描述(面试题),或者有清晰的需求,反而刚开始就一定定义好要声明的属性,是一个函数指针、指针、数组。

最后:
一定要记得C中的修饰符的意义和结合优先级–实在觉得记不住,多写几个括号也行。
*
表示一个指针
[]
表示一个数组
()
表示一个函数

结合优先级为()=[] > *

以上符号只在本文的是用范围内讨论,不涉及上述三个符号的其他用途。

float (**a)[10]

首先将**a看做一个整体T;
第一层定义是一个有10个元素的数组,数组里都是float类型的数据
第二层a是一个二级指针,该指针指向这个数组
a指向一个指针p,该指针指向q,q指向一个float example[10]的一维数组;

float *(*a)[10]

首先将*a看做一个整体T;
第一层定义这是一个指针的数组,数组长度为10,每个元素都是double *;
第二层T是一个指针,这个指针指向一个
“长度为10,每个元素都是一个double*”

double(*a[10])()

将*a[10]看做一个整体T;
第一层定义是一个函数,函数为double ,无输入参数;
第二层T,由于T是分符号优先级,[]的优先级大于*,
因此,这个T是一个数组,数组元素都是指针。 这些指针式指向第一层中的函数类型的。
因此a是一个函数指针组成的数组,该数组长度为10,数组元素都是指向double func()这
样函数的指针。

int*((*a)[10])

将(*a)[10]看做一个整体T,
第一层定义是一个指向int 类型的指针
第二层由于*a有括号,因此是一个指针,加上后面的[10],因此这是个指针的数组,数组长 
度为10。数组元素都是指针,这些指针(数组元素)都是指向第一层中(int *)的指针
另外:如果去掉最外面括号(按照优先级本来就可以去掉最外侧括号),同上面第二个解释

long (*a)()

a是一个函数指针,指向long f ();类型的函数

int (*(*a)(int,int))(int)

将(*(*a)(int,int))看做一个整体T:
第一层定义是一个函数,函数有一个int类型的返回值,一个int类型的输入值。
第二层首先判断这是个指针,这个指针必定是指向第一层的函数的,也就是((*a)
(int,int))整体是一个函数指针
第三层(*a)(int,int)是一个函数指针模样,因此a是一个函数指针,而该函数指针的返回
值类型是第二层中的指针,输入值是两个int类型。

int *a[10]:

由于[]的优先级高,因此后面a[10]表示一个数组,从左到右分析:
这是一个指针,分析a[10],这时一个数组,数组里是指针。

小结:
内层是指针,这个指针是指向外层类型
内层是数组,那这个数组的元素师外层类型
内层是函数的,这个函数的返回值是外层类型
——————————我是复杂的分割线—————————————
下面是描述,然后写出声明:
一个整型数:
a
一个指向整型数的指针
int *a
一个指向指针的指针,它指向的指针是一个指向一个整型数
int **a;
一个有10个整型数的数组
int a[10]
一个有10个指针的数组,该指针式指向一个整型数的
int *a[10]
定义是一个数组 一个指向有10个整型数数组的指针
int (*a)[10];
定义是一个指针一个指向函数的指针,该函数有一个整形 参数并返回一个整形数
int (*a)(int ,int);
一个有10个指针的数组,该指针指向一个有整形参数,返回一个整形数
int (*a[10])(int);
–最后这个函数指针的数组平时我以为用不到,但在翻看NXP提供的源代码里,这帮歪果仁特别喜欢在驱动中用这种函数指针数组,因为驱动的对外接口一般都是一样,什么init(),uinit(),io_write()等,于是这帮人各种这种声明,然后各种goto,果然驱动的代码是丑陋的啊!

typedef:把狼招来了

typedef是C提供的让用户可以为某一个类型创建自己名字。我们最常见的就是给结构体创建名字,然后就可以直接用新建的名字进行结构体创建,而省去关键字”struct”,或者”enum”。

下面我们首先看一下C Primer中对声明的花样玩法:(Page412)
int board[8][8]:
二维数组
int **ptr;
二级指针
int *risk[10]
优先级[]>*,从左到右,内层是数组,外层是指针
具有10个元素的数组
int (*risk)[10]:
外层是数组,内层是指针,
指向数组的指针
一个指针,指向具有10个元素的int数组
int * oof[3][4]
优先级[]>*,从左到右,内层是数组,外层是指针
一个3*4的数组,每个元素都是一个指向int的指针
int (*uuf)[3][4]
内层是指针,外层是数组,
指向数组的指针
int (*uof[3])[4]
第一层为数组 int TYPE_1 [4]
第二层为指针 *TYPE_2
第三层为数组
一个具有2个元素的数组,每个元素是一个指针,每个指针是指向具有4个元素的int数组的指针。
再说typdef招来的狼:
typedef int arry5[5]
arr5被定义成一个只有5个int元素的数组

typedef arr5 * p_arr5
定义p_arr5是指向arr5的指针,
typedef p_arr5 arrp10[10]
定义arrp10数组,数组中有10个元素,每个元素都是一个指向有5个int元素的数组
arr5 togs
p_arr5 p2
arrp10 ap;
——————————OVER——————————–

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
单链表是一种常见的数据结构,它由一个或多个节点组成,每个节点包含一个数据域和一个指针域,指针域指向下一个节点。 实现单链表的查找位序算法函数需要以下步骤: 1. 定义一个指针p指向链表的头节点,并定义一个变量count,用于计数。 2. 从头节点开始,遍历链表,当p指向某个节点时,计数器count加1。 3. 如果p指向的节点的数据与目标数据相等,则返回当前的计数器count,即为目标数据的位序。 4. 如果p指向的节点不是目标数据,则将p指向下一个节点,重复步骤3。 5. 如果遍历完链表后仍未找到目标数据,则返回-1,表示未找到。 下面是C语言实现单链表查找位序算法函数的代码示例: ```c #include <stdio.h> #include <stdlib.h> // 定义单链表节点结构 typedef struct Node { int data; // 数据域 struct Node* next; // 指针域 } Node; // 查找位序的算法函数 int findPosition(Node* head, int target) { Node* p = head; // 指向头节点 int count = 0; // 计数器初始化为0 while (p != NULL) { count++; // 计数器加1 if (p->data == target) { return count; // 找到目标数据,返回当前计数器的值 } p = p->next; // 指向下一个节点 } return -1; // 遍历完链表未找到目标数据,返回-1 } int main() { // 创建链表 Node* head = (Node*)malloc(sizeof(Node)); head->data = 1; // 头节点数据为1 Node* node1 = (Node*)malloc(sizeof(Node)); node1->data = 2; Node* node2 = (Node*)malloc(sizeof(Node)); node2->data = 3; head->next = node1; node1->next = node2; node2->next = NULL; // 查找位序示例 int target = 3; // 目标数据为3 int position = findPosition(head, target); if (position != -1) { printf("目标数据 %d 的位序为 %d\n", target, position); } else { printf("未找到目标数据 %d\n", target); } // 释放链表内存 free(node2); free(node1); free(head); return 0; } ``` 在上述代码,我们首先定义了一个指向头节点的指针p和一个计数器count,然后使用while循环遍历链表。当p指向某个节点时,计数器加1,并判断该节点的数据是否与目标数据相等。如果找到了目标数据,则返回当前计数器的值,即为目标数据的位序。如果遍历完链表仍未找到目标数据,则返回-1表示未找到。最后在主函数演示了调用该算法函数的示例。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值