结构体定义 typedef struct 用法详解和用法小结

       typedef可以声明新的类型名来代替已有的类型名,但却不能增加新的类型。
       typedef为C语言的关键字,作用是为一种数据类型定义一个新名字。这里的数据类型包括内部数据类型(int,char等)和自定义的数据类型(struct等)。
  在编程中使用typedef目的一般有两个,一个是给变量提供一个易记且意义明确的新名字(类型有新别名,方便变量的定义),另一个是简化一些比较复杂的类型声明。

typedef是类型定义的意思。typedef struct 是为了使用这个结构体方便。
具体区别在于:
若struct node {}这样来定义结构体的话。在申请node 的变量时,需要这样写,struct node n;
若用typedef,可以这样写,typedef struct node{}NODE; 。在申请变量时就可以这样写,NODE n;
区别就在于使用时,是否可以省去struct这个关键字。
 
分三块来讲述:
1 首先:
在C中定义一个结构体类型要用typedef:

typedef struct Student
{
int a;
}Stu;        //这里的Stu实际上就是struct Student的别名

于是在声明变量的时候就可:Stu stu1;
如果没有typedef就必须用struct Student stu1;来声明
这里的Stu实际上就是struct Student的别名。
另外这里也可以不写Student(于是也不能struct Student stu1;了)

typedef struct
{
int a;
}Stu;

但在c++里很简单,直接

struct Student
{
int a;
};

于是就定义了结构体类型Student,声明变量时直接Student stu2;

===========================================

2其次:
在c++中如果用typedef的话,又会造成区别:

struct Student
{
int a;
}stu1;//stu1是一个变量
typedef struct Student2
{
int a;
}stu2;//stu2是一个结构体类型

使用时可以直接访问stu1.a
但是stu2则必须先 stu2 s2;

然后 s2.a=10;

===========================================

3 掌握上面两条就可以了,不过最后我们探讨个没多大关系的问题
如果在c程序中我们写:

typedef struct
{
int num;
int age;
}aaa,bbb,ccc;

这算什么呢?
我个人观察编译器(VC6)的理解,这相当于

typedef struct
{
int num;
int age;
}aaa;


typedef aaa bbb;
typedef aaa ccc;

也就是说aaa,bbb,ccc三者都是结构体类型。声明变量时用任何一个都可以,在c++中也是如此。

但是你要注意的是这个在c++中如果写掉了typedef关键字,那么aaa,bbb,ccc将是截然不同的三个对象(这句话我没有理解)。


结构体也是一种数据类型, 可以使用结构变量, 因此, 像其它类型的变量一样, 在使用结构变量时要先对其定义。
定义结构变量的一般格式为:
struct 结构名
{
类型 变量名;
类型 变量名;
...
} 结构变量;
结构名是结构的标识符不是变量名。
另一种常用格式为:
typedef struct 结构名
{
类型 变量名;
类型 变量名;
...
} 结构别名;

另外注意: 在C中,struct不能包含函数。在C++中,对struct进行了扩展,可以包含函数。​​​​​​​

======================================================================

实例1: struct.cpp

#include <iostream>
using namespace std;

typedef struct _point
{
	int x;
	int y;
} point; //定义类,给类一个别名

struct _hello
{
	int x, y;
} hello; //同时定义类和对象

int main()
{
	point pt1;
	pt1.x = 2;
	pt1.y = 5;
	cout << "pt1.x = " << pt1.x << "  pt1.y = " << pt1.y << endl;
	//hello pt2;
	//pt2.x = 8;
	//pt2.y =10;
	//cout<<"pt2pt2.x="<< pt2.x <<"pt2.y="<<pt2.y <<endl;
	//上面的hello pt2;这一行编译将不能通过. 为什么?
	//因为hello是被定义了的对象实例了.
	//正确做法如下: 用hello.x和hello.y
	hello.x = 8;
	hello.y = 10;
	cout << "hello.x = " << hello.x << "   hello.y = " << hello.y << endl;
	return 0;

}

运行结果:

pt1.x = 2  pt1.y = 5
hello.x = 8   hello.y = 10

第五篇:问答
Q: 用struct和typedef struct 定义一个结构体有什么区别?为什么会有两种方式呢?
struct Student
{
int a;
} stu;


typedef struct Student2
{
int a;

}stu2;

A:
事实上,这个东西是从C语言中遗留过来的,typedef可以定义新的复合类型或给现有类型起一个别名,在C语言中,如果你使用
struct xxx
{
}; 的方法,使用时就必须用 struct xxx var 来声明变量,而使用
typedef struct xxx
{
}; 的方法 就可以写为 xxx var;
不过在C++中已经没有这回事了,无论你用哪一种写法都可以使用第二种方式声明变量,这个应该算是C语言的糟粕。

#include <iostream>
using namespace std;

typedef struct _point
{
	int x;
	int y;
} ; //定义类,给类一个别名

struct _hello
{
	int x, y;
} hello; //同时定义类和对象

int main()
{
	_point pt2;
	pt2.x = 55;
	pt2.y = 66;
	cout << "pt2.x = " << pt2.x << "  pt2.y = " << pt2.y << endl;
	_point pt1;
	pt1.x = 2;
	pt1.y = 5;
	cout << "pt1.x = " << pt1.x << "  pt1.y = " << pt1.y << endl;
	//hello pt2;
	//pt2.x = 8;
	//pt2.y =10;
	//cout<<"pt2pt2.x="<< pt2.x <<"pt2.y="<<pt2.y <<endl;
	//上面的hello pt2;这一行编译将不能通过. 为什么?
	//因为hello是被定义了的对象实例了.
	//正确做法如下: 用hello.x和hello.y
	hello.x = 8;
	hello.y = 10;
	cout << "hello.x = " << hello.x << "   hello.y = " << hello.y << endl;
	return 0;

}

用法小结

用途一:

定义一种类型的别名,而不只是简单的宏替换。可以用作同时声明指针型的多个对象。比如:

char* pa, pb;            // 这多数不符合我们的意图,它只声明了一个指向字符变量的指针 pa, 
                               // 和一个字符变量pb;
以下则可行:
typedef char* PCHAR;        // 一般用大写
PCHAR pa, pb;                    // 可行,同时声明了两个指向字符变量的指针
虽然:
char *pa, *pb;
也可行,但相对来说没有用typedef的形式直观,尤其在需要大量指针的地方,typedef的方式更省事。

用途二:

用typedef来定义与平台无关的类型。
比如定义一个叫 REAL 的浮点类型,在目标平台一上,让它表示最高精度的类型为:
typedef long double REAL; 
在不支持 long double 的平台二上,改为:
typedef double REAL; 
在连 double 都不支持的平台三上,改为:
typedef float REAL; 
也就是说,当跨平台时,只要改下 typedef 本身就行,不用对其他源码做任何修改。
标准库就广泛使用了这个技巧,比如size_t。
另外,因为typedef是定义了一种类型的新别名,不是简单的字符串替换,所以它比宏来得稳健(虽然用宏有时也可以完成以上的用途)。


注意:

记住, typedef是定义了一种类型的新别名,不同于宏,它不是简单的字符串替换。比如:
先定义:
typedef     char*   PSTR;
然后:
int mystrcmp(const PSTR, const PSTR);

const PSTR实际上相当于  const char*  吗?不是的,它实际上相当于char* const。
原因在于const给予了整个指针本身以常量性,也就是形成了指针常量char* const。
简单来说,记住当const和typedef一起出现时,typedef不会是简单的字符串替换就行。

补充: const修饰指针

const修饰指针有三种情况

指针常量和常量指针谁在后面谁是本质!!!

  1. const修饰指针(const 在 int *前,即常量指针)-- 常量指针(本质是指针,其指向的内存可以改变,指针指向的值不可以更改)
const int * p1 = &a; 
p1 = &b; //正确
//*p1 = 100;  报错
  1. const修饰常量(int *在 const 前,即指针常量) --- 指针常量(本质是常量,其指向的内存不可以变,指针指向的值可以更改)
int * const p2 = &a;
//p2 = &b; //错误
*p2 = 100; //正确

  1. const即修饰指针,又修饰常量
const int * const p3 = &a;
//p3 = &b; //错误
//*p3 = 100; //错误


C语言typedef(自定义数据类型)与#define(宏定义)总结

案例:
下面的代码中编译器会报一个错误,你知道是哪个语句错了吗?

	typedef char* pStr;
	char string[4] = "abc";
	const char* p1 = string;		// 常量指针
	const pStr p2 = string;			// char * const p2  指针常量,本质是常量,因此p2不可以被修改

	p1++;
	p2++;

是p2++出错了。这个问题再一次提醒我们:typedef和#define不同,它不是简单的文本替换。上述代码中const pStr p2并不等于const char * p2。const pStr p2和const long x本质上没有区别,都是对变量进行只读限制,只不过此处变量p2的数据类型是我们自己定义的而不是系统固有类型而已。因此,const pStr p2的含义是:限定数据类型为char *的变量p2为只读,因此p2++错误。

  • 10
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值