继上次分析C语言指针后,接分析c语言复杂指针以及typedef与define的作用以及区别

文章目录:

1.复杂指针讲解以及练习。

2.typedef与define作用以及区别。

3.用typedef对复杂指针重命名。

一。复杂指针讲解以及练习。

我觉得有一遍文章讲解讲解复杂指针非常好,直接引用过来。

下面第一段就是分析复杂指针的方法:

右左法则:首先从最里面的圆括号(未定义的标识符)看起,然后往右看,再往左看。每当遇到圆括号时,就应该掉转阅读方向。一旦解析完圆括号里面所有的东西,就跳出圆括号。重复这个过程直到整个声明解析完毕。

下面是例题讲解:(首先最基本的概念要理解,从简单开始)

int p;
这是一个普通的整型变量

int *p;
首先从p处开始, 先与*结合. 所以p是一个指针, 然后再与int结合. 说明p指向的为int型. 所以p是一个指向整型的指针变量

int p[n];
首先从p处开始, 先与[]结合, 所以p是一个数组, 然后再与int结合, 说明数组的元素为int型, 所以p是由n个int型数据的数组.

int *p[n];
从p处开始, 先与[]结合([]的优先级比*高), 所以p是一个数组, 然后再与*结合,说明数组的元素是指针类型, 再与int结合,说明指针的类型为整型,所以p是由n个int型指针的数组.

int (*p)[n]
从p处开始, 括号里面先执行, 先与*号结合, 说明p是一个指针. 然后再与[]结合,说明p指向的是一个数组. 再与int结合. 说明数组元素的值为int型, 所以p是一个指向由n个元素的数组的指针.

int **p
首先p与*结合, 说明p是一个指针, 然后再与*结合, 说明指针所指向的元素是指针. 再与int结合, 说明指针为int开进, 所以p是指向int型指针的指针.

int p(int)
首先p与()结合, 说明p是一个函数, 然后分析括号里面, 说明该函数接收一个int型的参数. 再与int结合, 说明该函数的返回值为int型

int (*p)(int)
首先p与*结合, 说明p是一个指针(括起p的括号起改变优先级), 然后与()结合说明p指向的是一个函数, 然后再与int结合说明函数的返回类型是整型.所以p是一个指向有一个整型参数, 返回值为整型的函数的指针.

int *(*p(int))[n]
从p开始先与()结合, 说明p是一个函数, 函数的参数为int型, 再与*结合, 说明函数的返回值为指针. 再与[]结合说明指针指向是一个数组,再与*结合说明数组的元素为指针, 再与int 结合说明数组的元素指针为int 型指针.所以p
 p是带一个int型参数返回值为指向n个int型指针元素的数组的函数

 

int (*func)(int *p);

首先找到那个未定义的标识符,就是func,它的外面有一对圆括号,而且左边是一个*号,这说明func是一个指针,然后跳出这个圆括号,先看右边,也是一个圆括号,这说明(*func)是一个函数,而func是一个指向这类函数的指针,就是一个函数指针,这类函数具有int*类型的形参,返回值类型是int。

int (*func)(int *p, int (*f)(int*)); 
func被一对括号包含,且左边有一个*号,说明func是一个指针,跳出括号,右边也有个括号,那么func是一个指向函数的指针,这类函数具有int *和int (*)(int*)这样的形参,返回值为int类型。再来看一看func的形参int (*f)(int*),类似前面的解释,f也是一个函数指针,指向的函数具有int*类型的形参,返回值为int。


int (*func[5])(int *p);

func右边是一个[]运算符,说明func是一个具有5个元素的数组,func的左边有一个*,说明func的元素是指针,要注意这里的*不是修饰func的,而是修饰func[5]的,原因是[]运算符优先级比*高,func先跟[]结合,因此*修饰的是func[5]。跳出这个括号,看右边,也是一对圆括号,说明func数组的元素是函数类型的指针,它所指向的函数具有int*类型的形参,返回值类型为int。

int (*(*func)[5])(int *p); 
func被一个圆括号包含,左边又有一个*,那么func是一个指针,跳出括号,右边是一个[]运算符号,说明func是一个指向数组的指针,现在往左看,左边有一个*号,说明这个数组的元素是指针,再跳出括号,右边又有一个括号,说明这个数组的元素是指向函数的指针。总结一下,就是:func是一个指向数组的指针,这个数组的元素是函数指针,这些指针指向具有int*形参,返回值为int类型的函数。

int (*(*func)(int *p))[5];

 func是一个函数指针,这类函数具有int*类型的形参,返回值是指向数组的指针,所指向的数组的元素是具有5个int元素的数组。
原文:https://blog.csdn.net/xuxhong/article/details/8182533 

2.typedef与define作用以及区别。

define(宏定义)形式:#define 标识符 字符串  #表示这是一个预处理命令,预处理不检查程序的对错。后面不用加 ‘;’号

作用:1.宏定义有两种形式:带参与不带参。宏定义计算时要注意优先级问题,它只是简单的替换。

           2.作为条件编译开关避免重复包含。 #ifndef *** #defnie *** #endif  *号代替文件名,两个是相同的。

           3.用于条件编译。#ifdef dosomething  #endif  或者 #ifden do  (#else do )  #endif 

           4.定义宏后取消: #undef *** * 表示宏名

typedef用法:

1.定义一种类型别名。

2.定义与平台无关的类型,大大减少改动代码劳动力。

比如定义一个real浮点类型,在一个平台上它可以表示为最高精度类型为:typedef long double real;

在系统移植后,新平台不支持long double 类型,哪我们只需要将typdef long double real; 中的类型该为支持且合适的。这样就大大减少了工作量。

3.为复杂的声明定义一个新的简单的名字。

define与typedef区别: define只是简单的一个替换,它不会做其他事情,而且在替换中经常有优先级的的问题。在预处理时,系统遇到define的宏就要替换。而typedef只替换一次就就行。

一个例子区别typedef,define:

typedef char * pStr;
char String[4] = "abc";
const char *p1=String;
const pStr p2 = String;
p1++;
p2++;

问p1++或p2++ 那个会出错?

答案是p2++会出错。因为typedef 的作用是定义一种类型别名。此题中,替换掉pStr后 const char * p2 =String;看似是对指向内容的封锁。然而不是。例如 const int a 一样,a在这里是一个常量。而typedef为char *起别名后为pStr,哪也就是const pStr p2中p2也是一个常量。所以此处p2是一个常量指针,而非指向物为常量。这块与一般的常量指针定义不一样,一般的是char* const p2;

然后也可以用define pStr char *试试,会发现p2是正确的。

3.用typedef对复杂指针重命名。

例子: int *(*A[10]) (int, char* );

直接一步替换:

typedef int *(*A[10]) (int, char* ); //重命名
int * test(int a,char *)
{
	int *p =new int(a);
	return p;
}
int main()
{
	A a;    //定义了一个复杂指针类型
	a[0] = test;
	int *p = a[0](10,0);
	cout<<*p<<endl;
	return 0;
}

可以从上面代码看到A 代替了一个类型,这个类型就是 存着函数参数为int,char*,返回值为int*类型的函数指针,数组大小为10.

所以A的本质是一个数组,只是里面存的是函数指针。所以就可以使用这样的代码a[0] =test;

分步替换:

 例子:void (*b[10]) (void (*)());

          先替换右边括号里面的参数,将void (*)()的类型起个别名pParam:       

           typedef void (*pParam) ();
          再替换左边的变量b,为b的类型起个别名B:

          typedef void (*B) (pParam);
          原声明的简化版: B b[10];
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值