c语言学习笔记之typedef
这是我觉得这个博主总结的很好转载过来的
原地址:https://blog.csdn.net/weixin_41632560/article/details/80747640
C语言语法简单,但内涵却博大精深;如果在学习时只是止步于表面,那么往往后期会遇到很多困 难。typedef是C语言中一个很好用的工具,大量存在于已有代码中,特别值得一提的是:C++标准库实现中更是对typedef有着大量的使用。但很 多初学者对其的理解仅局限于:typedef用来定义一个已有类型的"别名(alias)"。正是因为有了这样的理解,才有了后来初学者在typedef int myint和typedef myint int之间的犹豫不决。很多国内大学的C语言课之授课老师也都是如是说的,或者老师讲的不够透彻,导致学生们都是如是理解的。我这里想结合C语言标准文档 以及一些代码实例,也说说typedef。
int *p;
这样的代码是C语言中最最基础的一个语句了,大家都知道这个语句声明了一个变量p,其类型是指向整型的指针(pointer to int);如果在这个声明的前面加上一个typedef后,整个语义(semantics)又会是如何改变的呢?
typedef int *p;
我们先来看看C99标准中关于typedef是如何诠释的?C99标准中这样一小段精辟的描 述:"In a declaration whose storage-class specifier is typedef, each declarator defines an identifier to be a typedef name that denotes the type specified for the identifier in the way described in xx"。
参照这段描述,并拿typedef int *p作为例子来理解:在一个声明中,如果有存储类说明符typedef的修饰,标识符p将被定义为了一个typedef name,这个typedef name表示(denotes)一个类型,什么类型呢?就是int *p这个声明(declarator)中标识符(indentifier)p的类型(int*)。
再比对一下两个声明:
int *p;
typedef int *p;
是不是有点"茅舍顿开"的感觉,int *p中, p是一个变量,其类型为pointer to int;在int *p前面增加一个typedef后,p变为一个typedef-name(类型名字)(此时p可以当做一种类型来使用了),这个typedef-name(类型名字)所表示的类型就是int *p声明式中p的类型(int*)。说句白话,typedef让p去除了普通变量的身份,摇身一变,变成了p的类型的一个typedef-name(类型名字)了。
为了巩固上面的理解,我们再来看看"C语言参考手册(C: A Reference Manual)"中的说法:任何declarator(如typedef int *p)中的indentifier(如p)定义为typedef-name, 其(指代p)表示的类型是declarator为正常变量声明(指代int *p)的那个标识符(指代p)的类型(int*)。有些绕嘴,不过有例子支撑:
[例1]
typedef double MYDOUBLE;
分析:
去掉typedef ,得到正常变量声明=> double MYDOUBLE;
变量MYDOUBLE的类型为double;
=> "typedef double MYDOUBLE"中MYDOUBLE是类型double的一个typedef-name。
MYDOUBLE d; <=> d是一个double类型的变量
[例2]
typedef double *Dp;
分析:
去掉typedef ,得到正常变量声明=> double *Dp;
变量Dp的类型为double*,即pointer to double;
=> "typedef double *Dp"中Dp是类型double*的一个typedef-name(类型名字)。
Dp dptr; <=> dptr是一个pointer to double的变量
[例3]
typedef int* Func(int);
分析:
去掉typedef ,得到正常变量声明=> int* Func(int);
变量Func的类型为一个函数标识符,该函数返回值类型为int*,参数类型为int;
=> "typedef int* Func(int)"中Func是函数类型(函数返回值类型为int*,参数类型为int)的一个typedef-name。
Func *fptr; <=> fptr是一个pointer to function with one int parameter, returning a pointer to int
Func f; 这样的声明意义就不大了。
[例4]
typedef int (*PFunc)(int);
分析:
去掉typedef ,得到正常变量声明=> int (*PFunc)(int);
变量PFunc的类型为一个函数指针,指向的返回值类型为int,参数类型为int的函数原型;
=> "typedef int (*PFunc)(int)"中PFunc是函数指针类型(该指针类型指向返回值类型为int,参数类型为int的函数)的一个typedef-name。
PFunc fptr; <=> fptr是一个pointer to function with one int parameter, returning int

1 #include "iostream"
2
3 using namespace std;
4
5 int add(int a,int b){
6 return (a+b);
7 }
8
9 typedef int (* func)(int ,int ) ;
10
11 void main(){
12 func f = add;
13 int n = f(1,2);
14 cout << n << endl;
15 }

[例5]
typedef int A[5];
分析:
去掉typedef ,得到正常变量声明 => int A[5];
变量A的类型为一个含有5个元素的整型数组;
=> "typedef int A[5]"中A是含有5个元素的数组类型的一个typedef-name。
A a = {3, 4, 5, 7, 8};
A b = { 3, 4, 5, 7, 8, 9}; /* 会给出Warning: excess elements in array initializer */
[例6]
typedef int (*A)[5]; (注意与typedef int* A[5]; 区分)
分析:
去掉typedef ,得到正常变量声明 => int (*A)[5];
变量A的类型为pointer to an array with 5 int elements;
=> "typedef int (*A)[5]"中A是"pointer to an array with 5 int elements"的一个typedef-name。
int c[5] = {3, 4, 5, 7, 8};
A a = &c;
printf("%d\n", (*a)[0]); /* output: 3 */
如果这样赋值:
int c[6] = {3, 4, 5, 7, 8, 9};
A a = &c; /* 会有Warning: initialization from incompatible pointer type */
[例7]
typedef struct _Foo_t Foo_t;
分析:
去掉typedef ,得到正常变量声明 => struct _Foo_t Foo_t;
变量Foo_t的类型为struct _Foo_t;
=> "typedef struct _Foo_t Foo_t"中Foo_t是"struct _Foo_t"的一个typedef-name。
[例8]
typedef struct { ... // } Foo_t;
分析:
去掉typedef ,得到正常变量声明 => struct { ... // } Foo_t;
变量Foo_t的类型为struct { ... // } ;
=> "typedef struct { ... // } Foo_t "中Foo_t是"struct { ... // }"的一个typedef-name。这里struct {...//}是一个无"标志名称(tag name)"的结构体声明。
c语言学习笔记之typedef的更多相关文章
- HTML语言学习笔记(会更新)
		# HTML语言学习笔记(会更新) 一个html文件是由一系列的元素和标签组成的. 标签: 1.<html></html> 表示该文件为超文本标记语言(HTML)编写的.成对出 ... 
- 2017-04-21周C语言学习笔记
		C语言学习笔记:... --------------------------------- C语言学习笔记:学习程度的高低取决于.自学能力的高低.有的时候生活就是这样的.聪明的人有时候需要.用笨的方法 ... 
- 2017-05-4-C语言学习笔记
		C语言学习笔记... ------------------------------------ Hello C语言:什么是程序:程序是指:完成某件事的既定方式和过程.计算机中的程序是指:为了让计算机执 ... 
- GO语言学习笔记(一)
		GO语言学习笔记 1.数组切片slice:可动态增长的数组 2.错误处理流程关键字:defer panic recover 3.变量的初始化:以下效果一样 `var a int = 10` `var ... 
- Haskell语言学习笔记(88)语言扩展(1)
		ExistentialQuantification {-# LANGUAGE ExistentialQuantification #-} 存在类型专用的语言扩展 Haskell语言学习笔记(73)Ex ... 
- Go语言学习笔记十三: Map集合
		Go语言学习笔记十三: Map集合 Map在每种语言中基本都有,Java中是属于集合类Map,其包括HashMap, TreeMap等.而Python语言直接就属于一种类型,写法上比Java还简单. ... 
- Go语言学习笔记十二: 范围(Range)
		Go语言学习笔记十二: 范围(Range) rang这个关键字主要用来遍历数组,切片,通道或Map.在数组和切片中返回索引值,在Map中返回key. 这个特别像python的方式.不过写法上比较怪异使 ... 
- Go语言学习笔记十一: 切片(slice)
		Go语言学习笔记十一: 切片(slice) 切片这个概念我是从python语言中学到的,当时感觉这个东西真的比较好用.不像java语言写起来就比较繁琐.不过我觉得未来java语法也会支持的. 定义切片 ... 
- Go语言学习笔记十: 结构体
		Go语言学习笔记十: 结构体 Go语言的结构体语法和C语言类似.而结构体这个概念就类似高级语言Java中的类. 结构体定义 结构体有两个关键字type和struct,中间夹着一个结构体名称.大括号里面 ... 
随机推荐
- Scala 基础(四):Scala变量 (一) 基础
			1.概念 变量相当于内存中一个数据存储空间的表示,你可以把变量看做是一个房间的门 牌号,通过门牌号我们可以找到房间,而通过变量名可以访问到变量(值). 2 变量使用的基本步骤 1) 声明/定义变量 ( ... 
- 05 drf源码剖析之认证
			05 drf源码剖析之认证 目录 05 drf源码剖析之认证 1. 认证简述 2. 认证的使用 3. 源码剖析 4. 总结 1. 认证简述 当我们通过Web浏览器与API进行交互时,我们可以登录,然后 ... 
- dataframe一次小实验
			老师搞不清,一个ndarray[df['columns']==a],返回的是什么,目前看来应该是df[] == a 的索引 
- hihoCoder 1114 小Hi小Ho的惊天大作战:扫雷·一 最详细的解题报告
			题目来源:小Hi小Ho的惊天大作战:扫雷·一 解题思路:因为只要确定了第一个是否有地雷就可以推算出后面是否有地雷(要么为0,要么为1,如果不是这两个值就说明这个方案行不通),如果两种可能中有一种成功, ... 
- Azure Web App (二)使用部署槽切换部署环境
			一,引言 前天我们将到使用Azure的 Pass 服务 “Web App” 去部署我们的.NET Core Web项目,也同时有介绍到如何在VS中配置登陆中国区的Azure账号,今天接着讲,我们部署完 ... 
- 小谢第37问:关于websocket推送进度,本地保存进度条,然后跳出页面进入后再显示的问题
			1.主要技术点:sessionStorage 会话存储进度 这里在使用之前,顺便说一下cookie.sessionStorage.localStorage 共同点:都是保存在浏览器端,且同源的. 区别 ... 
- LGTB 与 序列
			题目描述 LGTB 有一个长度为 N 的序列 A ,现在他想构造一个新的长度为 N 的序列 B ,使得 B 中的任意两个数都互质.并且他要使 \sum_{1\le i\le N}|A_i-B_i| 最 ... 
- PyQt样式设计
			QSS QSS(Qt Style Sheets)即PyQt样式表,是用来定义控件外观的一种机制.QSS内部实现大量参考了CSS,但是功能没有CSS强大,主要体现在选择器少,属性少等. 使用QSS 格式 ... 
- 性能1.84倍于Ceph!网易数帆Curve分布式存储开源
			在上周刚结束的网易数字+大会上 网易数帆宣布: 开源一款名为Curve的高性能分布式存储系统, 性能可达Ceph的1.84倍! 网易副总裁.网易杭州研究院执行院长兼网易数帆总经理汪源: 基础软件的能力 ... 
- abp vnext 开发快速入门 3 实现权限控制
			上篇讲了abp vnext 实现了简单的增加操作的例子.删除更新查询基本类似,这里就不讲了,接下来说下如何实现角色权限控制. 再说之前,先说下如果想更加透彻的理解abp vnext的权限控制,最好是先 ... 
