指针数组和数组指针、函数指针以及typedef的用法

指针数组和数组指针

概念:
(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定义结构体变量类型

struct student
{
    
    
	char name[20];
	int age;
};

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定义结构体指针变量类型

struct student
{
    
    
	char name[20];
	int age;
};

typedef struct student
{
    
    
	char name[20];
	int age;
}student;

struct teacher
{
    
    
	char name[20];
	int age;
	int mager;
}

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 *(func)(char *a, char *b)
{
    
    
	printf("xxx\n");
}

则对应的函数指针为:

	char *(*pfunc)(char *a, char *b)

则,这个函数指针类型为:

	char *(*)(char *, char *);	

使用typedf改变类型:

	typedef char *(*pFunc)(char *, char *);	
	其中pFunc是自定义的类型名

下次定义函数指针时,只需要

 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;

猜你喜欢

转载自blog.csdn.net/shun1296/article/details/114753010
今日推荐