c/c++中typedef详解

1. typedef 最简单使用

你可以在任何需要 long 的上下文中使用 byte_4。注意 typedef 并不创建新的类型。它仅仅为现有类型添加一个同义字。

2. typedef 修饰数组

typedef char mySizes[100];   
mySizes xxx; 

typedef char [100] mySizes; //error
这里 mySize 就是一个大小为100的 char 数组,sizeof(mySize) 为 100。

3. typedef 修饰指针

这里有一个 typedef 陷阱。标准函数 strcmp()有两个‘const char *’类型的参数。因此,它可能会误导人们象上面这样声明。

按照顺序,‘const pstr’被解释为‘char * const’(一个指向 char 的常量指针),而不是‘const char *’(指向常量 char 的指针)。

其实这点很好理解,const 就是修饰 pstr 指针的,并不是简单替换

这个问题很容易解决:

4. typedef 修饰结构体

这语句实际上完成两个操作:
(1).定义一个新的结构类型

分析:

tagMyStruct ,实际上是一个临时名字,struct 关键字和 tagMyStruct一起,构成了这个结构类型,不论是否有typedef,这个结构都存在。

我们可以用 struct tagMyStruct xxName 来定义变量,但要注意,使用tagMyStruct xxxrName 来定义变量是不对的,因为struct 和tagMyStruct合在一起才能表示一个结构类型

(2). typedef 为这个新的结构起了一个名字,叫 MyStruct。

typedef struct tagMyStruct MyStruct;因此,MyStruct实际上相当于struct  tagMyStruct,我们可以使用MyStruct varName来定义变量。

 5. typedef & 结构的问题

在结构中包含指向它自己的指针


答案与分析:
    根据我们上面的阐述可以知道:要知道pNode表示的是类型的新名字,那么在类型本身还没有建立完成的时候,这个类型的新名字 pNoed 也还不存在,也就是说这个时候编译器根本不认识pNode。

解决这个问题的方法有多种:

// 1)
typedef struct tagNode   
{
  char *pItem;
  struct tagNode *pNext;   
} *pNode;   

// 2)   
typedef struct tagNode* pNode;   
struct tagNode   
{
  char *pItem;
  pNode pNext;
};
//注意:在这个例子中,你用 typedef 给一个还未完全声明的类型起新名字。C语言编译器支持这种做法。

// 3)规范做法:   
struct tagNode   
{
  char *pItem; 
  struct tagNode *pNext;   
};
typedef struct tagNode *pNode; 
6. typedef 与 #define的问题
有下面两种定义pStr数据类型的方法,两者有什么不同?哪一种更好一点?

答案与分析:

    通常讲,typedef要比#define要好,特别是在有指针的场合。
请看例子:


在上述的变量定义中,s4则定义成了char,不是我们所预期的指针变量,根本原因就在于#define只是简单的字符串替换而typedef则是为一个类型起新名字

上例中define语句必须写成 pStr2 s3, *s4; 这这样才能正常执行。

7. typedef 与 复杂的变量声明

在编程实践中,尤其是看别人代码的时候,常常会遇到比较复杂的变量声明,使用typedef作简化自有其价值,比如:   
下面是三个变量的声明,我想使用typdef分别给它们定义一个别名,请问该如何做?

int *(*a[5])(int, char*);

void (*b[10]) (void (*)());

double(*)() (*pa)[9]; 

答案与分析:

    对复杂变量建立一个类型别名的方法很简单,你只要在传统的变量声明表达式里用类型名替代变量名,然后把关键字typedef加在该语句的开头就行了。

8. typedef 修饰函数指针

//1. 定义一个函数指针
typedef int(_cdecl *FUN_Start)(UCHAR);
/* typedef的功能是定义新的类型。定义这种类型为指向某种函数的指针,这函数以一个UCHAO为参数并返回int类型。*/

//2. 定义这个函数指针的一个变量
FUN_Start fun_Start; 

//3. 把函数的地址赋给此函数指针
fun_Start = (FUN_Start)GetProcAddress(m_hLibrary,"Rec_SetDevice");

//4. 调用
if (fun_Start('a') == 1) //直接通过函数指针调用
{......}

//当然也可以这样
if ( (*)fun_Start('a') == 1) //先用*fun_start取出它所指的函数类型,再调用
{......}
因为函数名就是一个地址,该函数名所代表的函数的入口地址。

 

注:

总之一点,不要把typedef看成简单的替换,要看成一种新的命名,要与default相区别!!

发布了231 篇原创文章 · 获赞 513 · 访问量 120万+
展开阅读全文

怎么合并链表????

01-03

两个非降序链表的并集,例如将链表1->2->3 和 2->3->5 并为 1->2->3->5,只能输出结果,不能修改两个链表的数据。 #include <stdio.h> #include <stdlib.h> typedef int DataType; typedef struct node { DataType data; struct node *next; }*LinkList, *pNode; LinkList GetEmptyList() { LinkList head = (pNode)malloc(sizeof(struct node)); head->data = 0; head->next = 0; return head; } int AddNode(LinkList head, DataType data) { pNode newnode,p = head; while(p->next) { if(p->next->data == data) return 0; if(p->next->data > data) { newnode = (pNode)malloc(sizeof(struct node)); newnode->data = data; newnode->next = p->next; p->next = newnode; return 1; } p = p->next; } p->next = (pNode)malloc(sizeof(struct node)); p->next->data = data; p->next->next = 0; return 1; } LinkList MergeList(LinkList LA, LinkList LB) { // 合并LA、LB到新表 LinkList head; pNode p,q,t; int flag; head = p = GetEmptyList(); for(q = LA->next; q; q = q->next) { p->next = (pNode)malloc(sizeof(struct node)); p->next->data = q->data; p = p->next; } p->next = 0; for(p = LB->next; p; p = p->next) { // 合并 flag = 1; for(q = head; q->next && flag; q = q->next) { if(p->data == q->next->data) flag = 0; else if(p->data < q->next->data) { t = (pNode)malloc(sizeof(struct node)); t->data = p->data; t->next = q->next; q->next = t; flag = 0; } } if(flag) { q->next = (pNode)malloc(sizeof(struct node)); q->next->data = p->data; q->next->next = 0; } } return head; } void Show(LinkList head) { pNode p = head->next; while(p) { printf("%d ",p->data); p = p->next; } printf("\n"); } int main() { DataType x; LinkList LA = GetEmptyList(); LinkList LB = GetEmptyList(); LinkList LC; printf(""); while(scanf("%d",&x) == 1) { AddNode(LA,x); AddNode(LB,x); printf(""); } LC = MergeList(LA,LB); Show(LC); return 0; } 怎么好像不可以,怎么优化一下? 问答

为什么dev c代码修改以后编译运行仍然运行出原结果?

10-13

改之前的代码如下,后来删除了82和148行的cout,编译结果却没有变化,重开了dev c也仍然没法解决这个问题。 更改后结果仍然未变 ![图片说明](https://img-ask.csdn.net/upload/201910/13/1570935477_686763.jpg) 编译似乎也无问题![图片说明](https://img-ask.csdn.net/upload/201910/13/1570935832_663589.png) 而如果把代码复制重新重新编译能正确获得结果。 ``` #include<iostream> using namespace std; typedef struct StackNode { char data; struct StackNode *next; }StackNode,*LinkStack; typedef struct QNode { char data; struct QNode *next; }QNode,*QueuePtr; typedef struct { QueuePtr front; QueuePtr rear; }LinkQueue; class check { private: public: LinkQueue Q; LinkStack S; int CreateStack(LinkStack &S); int PushStack(LinkStack &S,char e); int PopStack(LinkStack &S,char &e); int GetStack(LinkStack &S,char &e); int CreateQueue(LinkQueue &Q); int EnterQueue(LinkQueue &Q,char e); int DeleteQueue(LinkQueue &Q,char &e); int checking(LinkQueue &Q,LinkStack &S); }; int check::CreateStack(LinkStack &S) { S=new StackNode; if(!S) { cout<<"error"<<endl; return 0; } S=NULL; return 1; } int check::PushStack(LinkStack &S,char e) { StackNode *q; q=new StackNode; q->data=e; q->next=S; S=q; return 1; } int check::PopStack(LinkStack &S,char &e) { if(S==NULL) return 0; StackNode *p; e=S->data; p=S; S=S->next; delete p; return 1; } int check::GetStack(LinkStack &S,char &e) { e=S->data; return 1; } int check::CreateQueue(LinkQueue &Q) { Q.front=Q.rear=new QNode; if(!Q.front) return 0; Q.front->next=NULL; cout<<"请输入:(结束前请输入 / )"<<endl; char e; cin>>e; while(e!='/') { EnterQueue(Q,e); cin>>e; cout<<e<<" "; } return 1; } int check::EnterQueue(LinkQueue &Q,char e) { QNode *p; p=new QNode; p->next=NULL; p->data=e; Q.rear->next=p; Q.rear=Q.rear->next; return 1; } int check::DeleteQueue(LinkQueue&Q,char &e) { QNode *p; p=Q.front->next; e=p->data; Q.front->next=p->next; if(Q.rear==p) { Q.rear=Q.front; return 0; } delete p; return 1; } int check::checking(LinkQueue &Q,LinkStack &S) { int i=1,t=0; char e; while(i!=0) { i=DeleteQueue(Q,e); t++; if(e=='('||e=='[') { PushStack(S,e); } else if(e==']') { char c; PopStack(S,c); if(c!='[') { cout<<"error: can't find [ , position:"<<t<<endl; return 0; } } else if(e==')') { char c; PopStack(S,c); if(c!='(') { cout<<"error: can't find ( , position"<<t<<endl; return 0; } } } if(PopStack(S,e)) { cout<<"error: can't find ] or ) to combo"<<endl; return 0; } /*这个if执行对每个左括号都需要右括号来配对的判断,原题目并不做此要求*/ cout<<i<<" "; return 1; } int main() { class check C; C.CreateStack(C.S); C.CreateQueue(C.Q); int k=0; k=C.checking(C.Q,C.S); if(k==1) cout<<"error:0"<<endl; return 0; } ``` 问答

C++实现链式队列,在Xcode遇到Thread 1: EXC_BAD_ACCESS (code=1, address=0x8)

11-29

代码是链式队列的构建,编译过程没问题,但是运行时提示Thread 1: EXC_BAD_ACCESS (code=1, address=0x8)。请问是什么原因造成的??这个问题已经困扰我很多次了 ![图片说明](https://img-ask.csdn.net/upload/201811/29/1543489395_62101.png) ``` #include <iostream> using namespace std; class qnode{ public: int data; qnode *link; }; class linkquene{ public: void QInit(linkquene &Q); void QInsert(linkquene &Q, int a); void QDelete(linkquene &Q); int isempty(linkquene &Q); void Qshow(linkquene &Q); private: qnode *rear; qnode *front; }; void linkquene::QInit(linkquene &Q) { qnode *p = new qnode; p->link = NULL; Q.front = p; Q.rear = p; } int linkquene::isempty(linkquene &Q) { if(Q.rear == Q.front){ return 1; } else return 0; } void linkquene::QInsert(linkquene &Q, int a) { qnode *n = new qnode; n->link = NULL; n->data = a; Q.rear->link = n; Q.rear = n; } void linkquene::QDelete(linkquene &Q) { qnode *n; n = Q.front->link; Q.front->link = Q.front->link->link; if(Q.rear == n) Q.rear = Q.front; delete n; } void linkquene::Qshow(linkquene &Q) { qnode *p; p = Q.front->link; while(p != NULL) { cout<<p->data<<endl; p = p->link; } } int main(int argc, const char * argv[]) { linkquene q; linkquene *Q; Q = new linkquene; q.QInsert(*Q, 10); q.QDelete(*Q); q.QInsert(*Q, 7); q.QInsert(*Q, 1); q.QInsert(*Q, 8); q.QDelete(*Q); q.Qshow(*Q); return 0; } ``` 问答

使用了未初始化的局部变量”t“在第74行

05-25

#include <stdio.h> //(1) #include <malloc.h>//(2) typedef int queuetype;//(3) queuetype num = 1;//(4) typedef struct qnode//(5) {//(6) queuetype data;//(7) struct qnode *next;//(8) }QNode;//(9) typedef struct//(10) {//(11) QNode *front, *rear;//(12) } QuType;//(13) void initlqueue(QuType *L)//(14) {//(15) L->front = L->rear = NULL;//(16) }//(17) void rudui(QuType *L, queuetype e)//(18) {//(19) QNode *p = (QNode*)malloc(sizeof(QNode));//(20) p->data = e;//(21) p->next = NULL;//(22) if (!L->front)//(23) {//(24) L->front = p;//(25) }//(26) if (L->rear)//(27) L->rear->next = p;//(28) L->rear = p;//(29) num++;//(30) }//(31) void shandui(QuType *L)//(32) {//(33) if (L->front)//(34) {//(35) QNode *p;//(36) p = L->front;//(37) printf("第%d位顾客已经点餐!\n", p->data);//(38) L->front = p->next;//(39) if (!p)//(40) L->rear = NULL;//(41) else//(42) free(p);//(43) }//(44) else//(45) {//(46) num = 0;//(47) printf("所有的顾客都已点餐完毕!\n");//(48) }//(49) }//(50) void xianshi(QuType *L)//(51) {//(52) QNode *p = L->front;//(53) printf("输出所有排队者的序号:\n");//(54) while (p)//(55) {//(56) printf(" %d\n", p->data);//(57) p = p->next;//(58) }//(59) if (!L->front)//(60) printf("顾客可坐下点餐!\n");//(61) }//(62) void chakan(QuType*L,queuetype e)//(63) {//(64) QNode *p = L->front, *q,*t;//(65) while(p&&p->data != e)//(66) {//(67) t = p; p = p->next;//(69) }//(70) if(p->data == e)//(71) {//(72) printf("fine!%d号即可进行点餐!\n", p->data);//(73) q = t->next;//(74) if (q->next)//(75) t->next = q->next;//(76) if (t->next == L->rear)//(77) t->next = L->rear = NULL; free(q);//(78) }//(79) else//(80) printf("队列中无此人!无需删除操作!\n");//(81) }//(82) //链队类型 void CanTing()//(83) {//(84) int sel, flag = 1;//(85) QuType *qu = (QuType*)malloc(sizeof(QuType));//(86) queuetype quik = 0;//(87) initlqueue(qu);//创建空队(88) printf("*******欢迎您的到来!******\n");//(89) printf("*******请排队就餐!******\n");//(90) while (flag == 1) //循环执行(91) {//(92) printf("1:排队 2:点餐 3:查看排队 4:VIP顾客 5:下班 请选择:");//(93) scanf_s("%d", &sel);//(94) switch (sel)//(95) { //排队,入队(96) case 1: rudui(qu, num); //(97) printf("\n排队成功!\n"); //(98) break;//(99) case 2: shandui(qu);//(100) printf("\n");//(101) break; //点餐,出队(102) case 3: xianshi(qu); //(103) break; //显示排队顾客(104) case 4://(105) {//(106) printf("若您需要马上就点,请输入您的号:");//(107) scanf("%d",&quik);//(108) chakan(qu,quik);//(109) printf("\n");//(110) } //(111) break; //任意顺序点餐(112) case 5: //(113) {//(114) printf("抱歉。已下班,营业结束,欢迎下次光临!\n\n");//下班(115) flag = 0; //退出(116) break;//(117) }//(118) default: //(119) printf("输入错误,请重新输入!\n\n"); //(120) continue;//(121) }//(122) }//(123) }//(124) void main()//(125) {//(126) CanTing();//(127) }//(128) ``` ``` 问答

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览