1.C/C++ typedef用法详解
2.C++ typedef & typename知识点总结
3.用C语言写的计算器源代码
4.typedefådefineå
·ä½ç详ç»åºå«
C/C++ typedef用法详解
typedef在C/C++中的四个核心用途:一、作为别名,简化代码编写,如在大量使用指针时,typedef能让声明更直观。
二、正规cpa源码在旧C代码中,typedef可以简化struct的使用,如从`struct 结构名 对象名`到`结构名 对象名`。
三、定义平台无关的类型,如REAL类型的浮点类型,根据目标平台调整类型。
四、为复杂声明提供简化别名,如将`int(*a[5])(int, char)`简化为`pFun a[5]`。
然而,typedef也有两大陷阱需要注意:typedef不是简单的字符串替换,如`const PSTR`不等于`const char*`,而是`char* const`。
typedef不能与其他存储类关键字一起使用,flash 项目源码如`typedef static int INT2`是无效的。
与#define相比,typedef在指针场景下更具优势,能避免一些常见问题。同时,typedef也常用于抑制不良代码,提升代码质量。 例如,typedef有助于创建平台无关的类型,比如在不同平台上定义REAL类型,jboss源码分析仅需更改typedef定义,无需修改源代码。C++ typedef & typename知识点总结
用过 C++ 的同学对 typename 和 typedef 相信并不是很陌生,但是当我看到下面这段代码的时候仍然无法理解:
按理来说 typedef 一般不是用来定义一种类型的别名,如下:
定义了一个 int 的别名是 SpeedType,那么我就可以这样用:
但是 typedef 后面接 typename 表示什么意思呢?typename 不是用来定义模板参数的吗?下面我们分别归纳一下 typedef & typename 的用法。
首先来看看 typedef 的几种常见用法。
为特定含义的类型取别名
这个我在上面已经讲过了,但是它是定义一种类型的别名,而不只是兔子博客 源码简单的宏替换,也可以用作同时声明指针型的多个对象的。
比如:
本来想要把 pa、pb 两个变量都声明为字符串,但是这样只能成功声明了一个。但是我们使用 typedef 就可以成功声明两个:
为结构体取别名
在声明变量的时候,需要带上 struct,即像下面这样使用:
用来定义与平台无关的类型
比如定义一个叫 REAL 的浮点类型,在目标平台一上,让它表示最高精度的类型为:
在不支持 long double 的平台二上,改为:
当跨平台时,地区查询 源码只要改下 typedef 本身就行,不用对其他源码做任何修改。
typename
typename 关键字用于引入一个模板参数,这个关键字用于指出模板声明(或定义)中的非独立名称(dependent names)是类型名,而非变量名:
typename 在这里的意思表明 T 是一个类型。如果没有它的话,在某些情况下会出现模棱两可的情况,比如下面这种情况:
作者想定义一个指针iter,它指向的类型是包含在类作用域T中的iterator。可能存在这样一个包含iterator类型的结构:
那么foo(); 这样用的是的时候确实可以知道 iter是一个ContainsAType::iterator类型的指针。但是T::iterator实际上可以是以下三种中的任何一种类型:
所以如果是下面这样的情况:
那T::iterator * iter;被编译器实例化为ContainsAnotherType::iterator * iter;,变成了一个静态数据成员乘以 iter ,这样编译器会找不到另一个变量 iter 的定义 。所以为了避免这样的歧义,我们加上 typename,表示 T::iterator 一定要是个类型才行。
得出结论
我们回到一开始的例子,对于vector::size_type,我们可以知道:
vector::size_type是vector的嵌套类型定义,其实际等价于 size_t类型。
那么这个例子的真是面目是,typedef创建了存在类型的别名,而typename告诉编译器std::vector::size_type是一个类型而不是一个成员。
加一个例子
好了,看了上面的例子你应该已经完全懂 typedef & typename 的精髓了,我们下面来讲解一个例子,用模板实现类似下面的循环:
首先我们需要一个循环模板:
这里应该可以看的懂,这几个模板,无论是 res_type 还是 type 都用 typename 修饰,表明都是类型,然后再接上 typedef 表示给这个类型定义了一个别名。
再定义循环模板的时候,有一个约定,它必须提供一个静态数据成员,cond_value,及两个子类型定义,res_type 和 next_type:
WhileLoop 用特化来决定走递归分支还是退出循环分支。
然后我们定义一个模板代表数值:
通过 value 可以获取到对应的数值,value_type 则是这个数值的类型。
通过上面的模板可以实现While<>::type>::type::value 1 加到 的结果。实际上就是通过类型的循环展开实现了 1 加到 运算结果。
用C语言写的计算器源代码
#include<stdio.h>
#include<iostream.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
typedef float DataType;
typedef struct
{
DataType *data;
int max;
int top;
}Stack;
void SetStack(Stack *S,int n)
{
S->data=(DataType*)malloc(n*sizeof(DataType));
if(S->data==NULL)
{
printf("overflow");
exit(1);
}
S->max=n;
S->top=-1;
}
void FreeStack(Stack *S)
{
free(S->data);
}
int StackEmpty(Stack *S)
{
if(S->top==-1)
return(1);
return(0);
}
DataType Peek(Stack *S)
{
if(S->top==S->max-1)
{
printf("Stack is empty!\n");
exit(1);
}
return(S->data[S->top]);
}
void Push(Stack *S,DataType item)
{
if(S->top==S->max-1)
{
printf("Stack is full!\n");
exit(1);
}
S->top++;
S->data[S->top]=item;
}
DataType Pop(Stack *S)
{
if(S->top==-1)
{
printf("Pop an empty stack!\n");
exit(1);
}
S->top--;
return(S->data[S->top+1]);
}
typedef struct
{
char op;
int inputprecedence;
int stackprecedence;
}DataType1;
typedef struct
{
DataType1 *data;
int max;
int top;
}Stack1;
void SetStack1(Stack1 *S,int n)
{
S->data=(DataType1*)malloc(n*sizeof(DataType1));
if(S->data==NULL)
{
printf("overflow");
exit(1);
}
S->max=n;
S->top=-1;
}
void FreeStack1(Stack1 *S)
{
free(S->data);
}
int StackEmpty1(Stack1 *S)
{
if(S->top==-1)
return(1);
return(0);
}
DataType1 Peek1(Stack1 *S)
{
if(S->top==S->max-1)
{
printf("Stack1 is empty!\n");
exit(1);
}
return(S->data[S->top]);
}
void Push1(Stack1 *S,DataType1 item)
{
if(S->top==S->max-1)
{
printf("Stack is full!\n");
exit(1);
}
S->top++;
S->data[S->top]=item;
}
DataType1 Pop1(Stack1 *S)
{
if(S->top==-1)
{
printf("Pop an empty stack!\n");
exit(1);
}
S->top--;
return(S->data[S->top+1]);
}
DataType1 MathOptr(char ch)
{
DataType1 optr;
optr.op=ch;
switch(optr.op)
{
case'+':
case'-':
optr.inputprecedence=1;
optr.stackprecedence=1;
break;
case'*':
case'/':
optr.inputprecedence=2;
optr.stackprecedence=2;
break;
case'(':
optr.inputprecedence=3;
optr.stackprecedence=-1;
break;
case')':
optr.inputprecedence=0;
optr.stackprecedence=0;
break;
}
return(optr);
}
void Evaluate(Stack *OpndStack,DataType1 optr)
{
DataType opnd1,opnd2;
opnd1=Pop(OpndStack);
opnd2=Pop(OpndStack);
switch(optr.op)
{
case'+':
Push(OpndStack,opnd2+opnd1);
break;
case'-':
Push(OpndStack,opnd2-opnd1);
break;
case'*':
Push(OpndStack,opnd2*opnd1);
break;
case'/':
Push(OpndStack,opnd2/opnd1);
break;
}
}
int isoptr(char ch)
{
if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='(')
return(1);
return(0);
}
void Infix(char *str)
{
int i,k,n=strlen(str);
char ch,numstr[];
DataType opnd;
DataType1 optr;
Stack OpndStack;
Stack1 OptrStack;
SetStack(&OpndStack,n);
SetStack1(&OptrStack,n);
k=0;
ch=str[k];
while(ch!='=')
if(isdigit(ch)||ch=='.')
{
for(i=0;isdigit(ch)||ch=='.';i++)
{
numstr[i]=ch;
k++;
ch=str[k];
}
numstr[i]='\0';
opnd= atof(numstr);
Push(&OpndStack,opnd);
}
else
if(isoptr(ch))
{
optr=MathOptr(ch);
while(Peek1(&OptrStack).stackprecedence>=optr.inputprecedence)
Evaluate(&OpndStack,Pop1(&OptrStack));
Push1(&OptrStack,optr);
k++;
ch=str[k];
}
else if(ch==')')
{
optr=MathOptr(ch);
while(Peek1(&OptrStack).stackprecedence>=optr.inputprecedence)
Evaluate(&OpndStack,Pop1(&OptrStack));
Pop1(&OptrStack);
k++;
ch=str[k];
}
while(!StackEmpty1(&OptrStack))
Evaluate(&OpndStack,Pop1(&OptrStack));
opnd=Pop(&OpndStack);
cout<<"你输入表达式的计算结果为"<<endl;
printf("%-6.2f\n",opnd);
FreeStack(&OpndStack);
FreeStack1(&OptrStack);
}
void main()
{
cout<<"请输入你要计算的表达式,并以“=”号结束。"<<endl;
char str[];
gets(str);
Infix(str);
=================================================================
哈哈!给分吧!
typedefådefineå ·ä½ç详ç»åºå«
#defineæ¯ç¼è¯é¢å¤çæ令ï¼å¨ç¼è¯é¢å¤çæ¶æ¢ï¼ä¸ä½æ£ç¡®æ§æ£æ¥ï¼ä¸è®ºæ¯å¦æ£ç¡®åªè¿è¡å¸¦å ¥æ¿æ¢ï¼åªæå¨ç¼è¯å·²è¢«å±å¼çæºç¨åºæ¶æä¼åç°å¯è½çé误并æ¥éã2.typedef为Cè¯è¨çå ³é®åï¼ä½ç¨æ¯ä¸ºä¸ç§æ°æ®ç±»åå®ä¹ä¸ä¸ªæ°ååã
两è çåºå«å¦ä¾ï¼
#define A int * tepedef int * Aï¼ï¼è¿æ¯ä¸æ¡è¯å¥ï¼è¦å åå·ï¼
两è çä½ç¨é½æ¯å°A代表int *ï¼ä½æ¯#defineå¨é¢å¤çæ¶è¿è¡ç®åçæ¿æ¢ï¼ètypedefä¸æ¯ç®åæ¿æ¢ã
typedefå®ä¹çAç¸å½äºå®ä¹äºä¸ä¸ªæéæåäºint *ãè#defineå®ä¹çAåªæ¯è¿è¡äºæ¿æ¢ã
æ©å±èµæï¼
typedef æå¦å¤ä¸ä¸ªéè¦çç¨éï¼é£å°±æ¯å®ä¹æºå¨æ å ³çç±»åï¼ä¾å¦ï¼ä½ å¯ä»¥å®ä¹ä¸ä¸ªå« REAL çæµ®ç¹ç±»åï¼å¨ç®æ æºå¨ä¸å®å¯ä»¥è·å¾æé«ç精度ï¼
typedef long double REAL;
å¨ä¸æ¯æ long double çæºå¨ä¸ï¼è¯¥ typedef çèµ·æ¥ä¼æ¯ä¸é¢è¿æ ·ï¼
typedef double REAL;
并ä¸ï¼å¨è¿ double é½ä¸æ¯æçæºå¨ä¸ï¼è¯¥ typedef çèµ·æ¥ä¼æ¯è¿æ ·ï¼
typedef float REAL;
ä½ ä¸ç¨å¯¹æºä»£ç åä»»ä½ä¿®æ¹ï¼ä¾¿å¯ä»¥å¨æ¯ä¸ç§å¹³å°ä¸ç¼è¯è¿ä¸ªä½¿ç¨ REAL ç±»åçåºç¨ç¨åºãå¯ä¸è¦æ¹çæ¯ typedef æ¬èº«ãå¨å¤§å¤æ°æ åµä¸ï¼çè³è¿ä¸ªå¾®å°çåå¨å®å ¨é½å¯ä»¥éè¿å¥å¦çæ¡ä»¶ç¼è¯æ¥èªå¨å®ç°ãä¸æ¯å? æ ååºå¹¿æ³å°ä½¿ç¨ typedef æ¥å建è¿æ ·çå¹³å°æ å ³ç±»åï¼size_tï¼ptrdiff
å fpos_t å°±æ¯å ¶ä¸çä¾åãæ¤å¤ï¼è±¡ std::string å std::ofstream è¿æ ·ç typedef
è¿éèäºé¿é¿çï¼é¾ä»¥ç解ç模æ¿ç¹åè¯æ³ï¼ä¾å¦ï¼basic_stringï¼allocator> å basic_ofstream>ã
åèèµæï¼typedef-ç¾åº¦ç¾ç§