[C++ rudiment][转]typedef 使用

typedef似乎很简单,如typedef int integer;然而,这些简单的typedef语句容易让人产生一种误解,typedef就是一种宏替换,把后面的自定义类型替换成前面的已知类型,事实是这样的吗?显然不是!

 首先可以肯定的是,我们不能这样去理解,因为虽然我们按照这样的理解方式去理解对于上面这种形式(typedef int integer)可以通过,但是对于其它方式是通不过的。

  考虑这样的问题:如何定义一个指向整型的指针类型?如何定义一个函数指针类型?

 第一个问题很简单:typedef int* int_pointer;即可,对于第二个问题,似乎就没有那么简单了,首先,看函数指针的定义方法:int (*p)(const&, int); 这个p指向的函数必须返回int,形参必须是const&int。现在要将这种指针类型命名为func_pointer,其定义的方法如下:

typedef int (*func_pointer)(const&, int);

按照以下方式理解就是正确的了:typedef int integer;typedef去掉,那就是个变量的定义,这儿即定义了一个int型的变量integer,考虑这个integer是什么类型的,那么这个typedef语句就是将integer定义为这个类型的。将typedef int (*func_pointer)(const&, int);中的typedef去掉,就成了一个函数指针定义,即func_pointer被定义为函数指针类型变量,那么原来的typedef即将func_pointer定义为函数指针类型。

 int (*testCases[10])();

   这个表达式是什么意思?指针,数组,函数糅合在了一起问题变得复杂起来。它定义了数组,testCases[10],数组中的元素是函数指针,函数指针的类型是 int (*)();

   怎么来理解这种定义呢?首先考虑数组的定义,数组的定义一般模式是:类型 数组名[大小];

考虑这个表达式,似乎是定义了一个数组,但是数组名[大小]被夹在了中间,那么类型是什么呢,发现类型并不是简单的数据类型,而是一个函数指针类型int (*p)(),这个函数没有参数,返回int型。从而这个表达式的含义是:定义了一个函数指针型的数组,大小是10。可以利用typedef来简化这种定义:

typedef int (*PFV)();

PFV testCases[10];

其实int (*testCases[10])();这儿我们定义了一个函数指针数组,数组是主体。

 

下面考虑这样的问题:如何定义一个指向数组的指针?

   指向数组的指针,好像比较新鲜,所谓指向数组的指针,即指针的一步跨越是一个数组,跟指向整型的指针一步跨越一个整型一个道理。事实上前面已经碰到了指向数组的指针,如二维数组名,实际上就是一个指向数组的指针,它一次跨越一行的数据,实际上即是跨越了一个一维数组,而三维数组名呢,也是一个指向数组的指针,它一次跨越的是低维组成的一个二维数组。

   数组指针(即指向数组的指针)的定义: int (*ptr)[3]; 

   这个表达式定义了一个数组指针ptrptr一次跨越一个由3int型组成的一维数组。发现其定义的方式与函数指针定义的方式很相似,只是把()换作了[]。更进一步,如果要定义一个指向数组的指针,而数组中的元素不是简单的int型,而是比较复杂的类型,那该如何定义呢?事实上数组指针这种东西就已经够稀有的了,一般编程绝对不会用到,我们只需要能读懂一些比较复杂的东西就行了,自己没有必要构造这么复杂的类型。

 

比较复杂的表达式:

1int (*(*(*p())[])())[];

   首先,根据p()判断p是一个函数,再根据p()前面的*号判断该函数返回一个指针,下面就看这个指针指向的是什么类型了,我们可以把*p()替换成一个*pointer,这个pointer就是函数p返回的指针,那么就成了int (*(*(*pointer)[])())[];再根据(*pointer)[],这说明了指针pointer是指向的一个数组,那么这个数组中的元素是什么类型呢?由于数组名实际上就是个指针,我们把(*pointer)[](即(*p())[])替换成一个array,这样就成了 int (*(*array)())[];发现array是一个函数指针,从而数组中的每个元素是函数指针,而这个函数呢,又返回一个指针类型,把(*array)()func代替,就成了int (*func)[];这说明了func函数返回的是指向数组的指针,数组中的元素是int型。

这个表达式够酷!!!

 

2p = (int( * (*)[20])[10])q;

   这是一个强制类型转换,q被强制类型转换成一个这样的指针类型,这个指针呢直线一个具有20个元素的数组,这个数组中的元素也是指针,是指向另外一种数组,这种数组是含有10int型数据的一维数组。

 

   可见,分析复杂的表达式时(所谓复杂,即糅合了指针,数组,函数三样,缺少了一样就不会复杂了),从括号的最里层做起,最里层的东西是复杂表达式的根节点,然后一层一层脱,脱的时候,是这样的,比如里层是个数组,那么就是说这个数组的元素是什么呢,那就是外层的东西,如果里层是个有返回值的函数,那么就是说这个函数返回什么值呢?那就是外层的东西,就这样一层一层地把表达式解析清楚。

关于typedef还有一些要说的:

typedef  int (*PFV)(); 这是定义了一个函数指针,那么PFV p;就可以定义了一个指向函数的指针。

typedef int (*p[10])(); 这是把p定义为函数指针数组,那么 p array;语句就可以定义了一个函数指针数组,数组名即为arrayarray这个数组含10个元素。

typedef int (*parray)[3];这是定义了一个指向整型数组的指针,那么 parray ptr;就定义了一个指向数组的指针。如何对这个ptr赋值或者初始化呢?事实上,是通过二维数组名来对其进行赋值(初始化)的,因为二维数组名作为指针来讲,就是一个指向数组的指针,一次跨越一个数组。

typedef int a[3][3]; 这个语句什么意思呢?这是把a定义为一个3*3的整型数组类型。当a b = {1}时就完成了一个3×3的整型数组的定义初始化的工作。

同样,简单一点 typedef int a[3];这个语句是把a定义为一个一维数组类型。

typedef  void func(int); 这个语句定义了一个函数类型。通过这个typedef,我们可以比较清晰地定义出函数指针,func* p;即可。

 

typedef char* string;

const string str;

这个str是什么类型的呢?const char * str,即指向常量的指针类型?事实上,答案有些不可思议,str是一个常量指针,而不是指针常量,即const修饰符针对的是指针,而不是char

 

转载于:https://www.cnblogs.com/krisdy/archive/2009/06/15/1503689.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/363188.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

预留空间过大的OutOfMemoryError

在分配一个应该很适合我为JVM提供的堆中的数据结构时,为什么会出现OutOfMemoryError? 这是我最近遇到的一个问题。 确实,当查看开发人员要完成的工作并通过-Xmx参数对提供给JVM的堆大小进行三重检查时,似乎确实存在着一些可疑之处…

查看系统剩余空间

1.剩余空间:df -h 2.追踪最耗费硬盘的文件位置 cd /du -h --max-depth1 | sort -rn 转载于:https://www.cnblogs.com/xiaobiaomei/p/10669159.html

【转】理解POCO

理解POCO(Plain Old CLR Object)先要理解POJO。 1、什么是POJO? POJO的名称有多种,pure old java object 、plain ordinary java object 等。  按照Martin Fowler的解释是“Plain Old Java Object”,从字面上翻译为“纯洁老式的java对象”&#xff0c…

『ExtJS』01 001. ExtJS 4 类的定义

ExtJS 4 类的定义类的定义与类方法的调用 样例代码// Define new class Vehicle under the Cookbook namespaceExt.define(Cookbook.Vehicle, {// class configuration goes hereManufacturer : Aston Martin,Model : Vanquish,getDetails : function() {alert(I am an this…

HashMap底层实现原理及面试问题

①HashMap的工作原理 HashMap基于hashing原理,我们通过put()和get()方法储存和获取对象。当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算hashcode,让后找到bucket位置来储存值对象。当获取对象时,通过键对象…

Neo4j 2.1:传递节点ID与UNWIND

在发布Neo4j 2.1时,我们将具有UNWIND子句,该子句使处理事物集合更加容易。 在我的有关创建邻接矩阵的博客文章中,我们想要显示按字母顺序排列的前5个见面组中有多少人,然后检查其他各组中有多少人。 没有UNWIND子句,…

使用C#調用外部程式或是執行DOS命令

在.NET裡要如何調用外部程式呢?? 在.net裡,提供了Process類,提供我們強大的調用外部工具功能,並透過重新導向輸入與輸出,可以取得執行結果,下面就用一個例子來示範在一個WinForm裡輸入一個Dos命令,然後呼…

flex 学习篇 ---- 导航类容器

导航类容器需要使用<mx:ViewStack />。可以直接从ui设计器中拉控件过去舞台或者手动敲代码。 导航类容器就是相当于创建了一个菜单&#xff0c;然后按每个选项都可以进入到不同的页面。 创建了<mx:ViewStack>之后需要为它指定id号。 <mx:ViewStack id"vi…

SQLiteOpenHelper+ContentProvider的使用

效果图&#xff1a; PetDbHelper package com.example.admin.pets;import android.content.Context;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteOpenHelper;import com.example.admin.pets.PetContract.PetEntry;public class PetDb…

[Mac入门] 如果更快的打开程序或文件

今天有位网友问我在Windows下可以用CtrlR快速打开程序/文件夹等&#xff0c;在Mac下有没有相类似的功能&#xff1f;本文将介绍一些我的一般做法。 1.Windows下的CtrlR是什么&#xff1f; 我打算从解释CtrlR开始说起&#xff0c;希望朋友们别嫌烦&#xff5e;。Windows下系统全…

Install Shield制作安装包技巧(SQL篇)

1、检查SQL Server是否安装prototype CheckSQL(); function CheckSQL()BOOL bSuccess;NUMBER nType, nvSize;STRING szVer; STRING szSetupVer, szSetupPath;beginRegDBSetDefaultRoot ( HKEY_LOCAL_MACHINE );szSetupPath "SOFTWARE\\Microsoft\\MSSQLServer\\Setup&quo…

ActiveMQ –经纪人网络解释–第4部分

在前面的第3部分中 &#xff0c;我们已经看到ActiveMQ如何帮助将远程使用者与本地使用者区分开来&#xff0c;这有助于确定从消息生产者到使用者的较短路径。 在第4部分中&#xff0c;我们将研究如何在远程代理上负载均衡并发使用者。 让我们考虑一些高级配置&#xff0c;以平…

总结CSS3新特性(选择器篇)

CSS3新增了嗯- -21个选择器,脚本通过控制台在这里运行; ~: p ~ p {color : red;/*此条规则将用于p后边所有的p...就是除了第一个p的所有p,规则同p:not(:nth-of-type(1)),但是权重要低于后者*/} [attribute^value]: 选择该属性以特定值开头的元素 [attribute$value]: 选择该属…

js获取地址栏信息

设置或获取对象指定的文件名或路径。 window.location.pathname例&#xff1a;http://localhost:8086/topic/index?topicId361alert(window.location.pathname); 则输出&#xff1a;/topic/index设置或获取整个 URL 为字符串。window.location.href例&#xff1a;http://local…

在NIO.2中使用文件和目录

在先前的文章中&#xff0c;我讨论了文件和目录的创建&#xff08; 创建文件和目录 &#xff09;以及选择&#xff08; 列出和过滤目录内容 &#xff09;。 采取的最后一个合乎逻辑的步骤是探索我们如何使用它们以及如何使用它们。 这是库的一部分&#xff0c;它经过了重新设计…

工作流的设计,业务流程图的绘制与编辑,工作流软件,工作流源代码组件库,开发平台,开发引擎...

基于业务流程的工作流系统在当前的软件工业中占据着非常重要的部分&#xff0c;开发此类系统, 最困难的部分就是业务流程建模和电子表单的可视化界面部分,这部分界面要求有快速的响应时间, 完善的逻辑关系,以及根据需求不断变化而必须具备的灵活编辑功能. E-Form可视化图形源码…

upload file more than 4MB

http://www.websupergoo.com/abcupload.net-1.htm 转载于:https://www.cnblogs.com/stevengeng/archive/2004/12/30/84274.html

Ajax全接触(1)

Ajax全称&#xff1a;Asynchronous JavaScript and XML(异步的JavaScript和XML) .Ajax不是某种编程语言 是一种在无需重新加载整个网页的情况之下能够更新部分网页的技术。 后面引入XMLHttpRequest对象用于后台和服务器交换数据&#xff0c;可以在不重新加载整个页面的前提下…

关于hibernate字段映射@colunm出现的问题以及jpa驼峰大写转_小写的问题探究

关于hibernate字段映射colunm出现的问题以及jpa驼峰大写转_小写的问题探究2018年04月24日 15:47:26 守望dfdfdf 阅读数&#xff1a;735 标签&#xff1a; colunmhibernate表映射实体类 更多个人分类&#xff1a; 工作 问题编辑版权声明&#xff1a;本文为博主原创文章&#xff…

窗口模版

窗口模版 1. 定义窗口模版的ID 在wgui_categories_defs.h文件中有枚举enum MMI_CATEGORY_ID_LIST 首先要在MMI_CATEGORY_ID_LIST中添加窗口模版的ID&#xff0c;例如&#xff1a; MMI_CATEGORY36_ID 2. 控件坐标和控件数组的定义 CustCoordinates.c (plutommi"…