指针数组和数组指针
概念:
(1)指针数组:指针数组是一个数组,数组元素是指针。
(2)数组指针的实质是一个指针,这个指针指向的是一个数组。
表达式:
int *p[5] //等效于int *(p[5]),这两个都是指针数组
int (*p)[5] //指针被括起来,是数组指针
关于优先级:[] . ->这三个优先级比较高
函数指针
概念:
函数指针也是一个指针,指针就是指针变量(32位电脑占4个字节,64位电脑占8个字节)
表达式:
假设:
void func(void)
{
printf("666\n");
}
函数指针的定义:
其实,函数指针的定义,其实就是赋值函数定义的第一句,把函数名改成指针再加个括号即可。
void (*pfunc)(void);
定义完后,要让函数指针指向该函数
pfunc = func;
或者:
pfunc = &func;
注:函数名和数组名最大的区别就是:函数名做右值时加不加&效果和意义都是一样的;但是数组名做右值时加不加&意义就不一样
函数指针实战
(1) 功能:实现结构体内嵌函数指针实现分层
(2)本程序要完成一个计算器我们设计了2个层次:
上层是framework.c,实现应用程序框架;
下层是cal.c,实现计算器。
实际工作时cal.c是直接完成工作的,但是cal.c中的关键部分是调用的framework.c中的函数来完成的。
(3)先写framework.c,在framework.c中需要完成计算器的业务逻辑,并且把相应的接口写在对应的头文件中发出来,将来别的层次的人用这个头文件来协同工作。
cal.h(初步定义,不完整)
typedef int(*pFunc)(int a,int b);
struct cal
{
int a;
int b;
pFunc p1;
};
framework.c
#include "cal.h"
int add(int a,int b)
{
return a+b;
}
int sub(int a,int b)
{
return a-b;
}
int multiply(int a,int b)
{
return a*b;
}
int divide(int a,int b)
{
return a/b;
}
int cal(struct cal *p)//此函数就是接口函数,在头文件中声明好,并且备注好参数意义,让cal.c的程序员直接输入数据调用即可。
{
return(p->p1(p->a,p->b));//p1,a,b早已在cal.h中定义好了。
}
写完framewor.c后,补全cal.h,定义的函数都要声明。
cal.h
typedef int(*pFunc)(int a,int b);
int add(int a,int b);//加法
int sub(int a,int b);//减法
int multiply(int a,int b);//乘法
int divide(int a,int b);//除法
struct cal
{
int a;
int b;
pFunc p1; //p1为add、sub、multiply、divide其中一个
//int(*p1)(int a,int b);
};
int cal(struct cal *p); //接口函数,直接调用即可计算
cal.c
写cal.c是建立在有cal.h的情况下
#include "cal.h"
#include <stdio.h>
int main()
{
struct cal cal_t;
int ret = 0;
//这里直接定义数字了,没用sacnf,嫌麻烦
cal_t.a = 12;
cal_t.b = 4;
cal_t.p1 = divide;
ret = cal(&cal_t);
printf("ret = %d\n",ret);
}
再论typedef
(1)typedef和define的区别:
1.define只是简单的字符串替换而typedef则是为一个类型起新名字。
2.typedef是定义数据类型(但没有创造新的数据类型),而define是定义变量名称
3.结合指针时的区别:
#define dpChar char *
typedef char * tpChar; // typedef用来重命名类型,或者说用来制造用户自定义类型
int main()
{
dpChar p1, p2; // char *p1, p2; 相当于char *p1, char p2;
tpChar p3, p4; // 等价于:char *p3, char *p4;
printf("sizeof(p1) = %d.\n", sizeof(p1)); // 8
printf("sizeof(p2) = %d.\n", sizeof(p2)); // 1
printf("sizeof(p3) = %d.\n", sizeof(p3)); // 8
printf("sizeof(p4) = %d.\n", sizeof(p4)); // 8
(2)typedef和结构体
2.1用typedef定义结构体变量类型
typedef struct student
{
char name[20];
int age;
}student;
int main()
{
struct student s1; // struct student是类型;s1是变量
s1.age = 12;
student s2;
}
2.2 用typedef定义结构体指针变量类型
typedef struct student
{
char name[20];
int age;
}student;
typedef struct teacher
{
char name[20];
int age;
int mager;
}teacher, *pTeacher;//这样可以生成 结构体指针变量
struct student *pS1; // 结构体指针
student *pS2; // 同上
teacher t1;
t1.age = 23;
pTeacher p1 = &t1;
printf("teacher age = %d.\n", p1->age);
(3) typedef与const
第一种:const int *p; //指向的内容不可改,本身可改
第二种:int const *p; //指向的内容不可改,本身可改
第三种:int * const p; //指向的内容可改,本身不可改
第四种:const int * const p; //指向的内容不可改,本身不可改
typedef int *PINT; const PINT p2; //相当于是int *const p2;
typedef int *PINT; PINT const p2; //相当于是int *const p2;
typedef const int *CPINT; CPINT p1;//相当于是const int *p
(4使用typedef的重要意义
4.1简化类型
4.2创造平台无关类型
(1)简化函数指针类型的描述。
比如有一个函数指针类型:
char *(*)(char *, char *);
typedef char *(*pFunc)(char *, char *);
下次定义函数指针时,只需要
pFunc p1; //代替了char *(*p1)(char *, char *);
pFunc p2; //代替了char *(*p2)(char *, char *);
pFunc p3; //代替了char *(*p3)(char *, char *);
(2)创造平台无关类型
typedef int size_t; //size_t代替int,可赋予变量类型实际含义
typedef int len_t;