C++ typedef

C++ 中,typedef 是一个关键字,用于为已有的数据类型定义一个新的名字(别名)。这有助于简化复杂类型的书写,提高代码的可读性和可维护性。它与宏定义有些差异。它本身是一种存储类的关键字,与auto、extern、mutable、static、register等关键字不能出现在同一个表达式中。本文主要介绍C/C++中typedef的使用。

1、typedef定义及使用

使用typedef关键字为指定类型取一个别名,可以为char*取一个别名为pStr

例如,

typedef   char* pStr;

例如,

#include <iostream>
using namespace std;
#include <string.h>
typedef struct Books
{
   char  title[50];
   char  author[50];
   char  subject[100];
   int   book_id;
} Book;
int main( )
{
   Book book;
   strcpy( book.title, "C 教程");
   strcpy( book.author, "cjavapy"); 
   strcpy( book.subject, "编程语言");
   book.book_id = 1;
   cout << "书标题 : " << book.title << endl;
   cout << "书作者 : " << book.author << endl;
   cout << "书类目 : " << book.subject << endl;
   cout << "书 ID : " << book.book_id << endl;
   return 0;
}

1)使用简单别名

#include<iostream>
using namespace std;

typedef unsigned int uint;

int main() {
  // 使用简单别名
  uint age = 25;
  cout << "Age: " << age << endl;
  return 0;
}

2)使用指针别名

#include<iostream>
using namespace std;

typedef int* IntPtr;

int main() {
   // 使用指针别名
  IntPtr p = new int(42);
  cout << "Pointer value: " << *p << endl;
  delete p;
  return 0;
}

3)使用结构体别名

#include<iostream>
using namespace std;

struct Point {
    int x, y;
};
typedef struct Point PointAlias;

int main() {
  // 使用结构体别名
  PointAlias point = {10, 20};
  cout << "Point: (" 
  << point.x << ", " << point.y 
  << ")" << endl;
  return 0;
}

4)使用函数指针别名

#include<iostream>
using namespace std;

typedef void (*Callback)(int, int);

void myFunction(int a, int b) {
    cout << "Callback called with: " << a << ", " << b << endl;
}

int main() {
  
  // 使用函数指针别名
  Callback cb = myFunction;
  cb(5, 10);
  return 0;
}

2、typedef 与 C++ 中的 using

在 C++(C++11 及以上)中,typedef 的功能可以由 using 替代,using 提供了更简洁的语法,尤其在模板场景下更为灵活。typedef 无法直接用于模板,而 using 可以轻松处理模板类型别名。using 的语法更直观,很多开发者认为它更易读。

1)使用using的示例

#include<iostream>
using namespace std;
#include <vector>

// 简单类型别名
using uint = unsigned int;
// 指针类型别名
using IntPtr = int*;
// 结构体类型别名
struct Point {
    int x, y;
};
using PointAlias = Point;
// 函数指针类型别名
using Callback = void(*)(int, int);

void myFunction(int a, int b) {
    cout << "Callback called with: " << a << ", " << b << endl;
}

int main() {
    uint age = 25;
    cout << "Age: " << age << endl;

    IntPtr p = new int(42);
    cout << "Pointer value: " << *p << endl;
    delete p;

    PointAlias point = {10, 20};
    cout << "Point: (" << point.x << ", " << point.y << ")" << endl;

    Callback cb = myFunction;
    cb(5, 10);
    return 0;
}

2)用于模板的类型别名

#include<iostream>
using namespace std;
#include <vector>

// 模板类型别名(`using` 支持模板)
template<typename T>
using Vec = vector<T>;

int main() {

    Vec<int> vec = {1, 2, 3};
    cout << "Vector elements: ";
    for (int num : vec) {
        cout << num << " ";
    }
    cout << endl;

    return 0;
}

3、typedef 和 #define区别

typedef定义一种类型的别名,而不是简单的宏替换。

1)typedef 仅限于为类型定义符号名称,#define 不仅可以为类型定义别名,也能为数值定义别名,比如可以定义 1ONE

2)typedef 是由编译器执行解释的,#define 语句是由预编译器进行处理的。

例如,

typedef char* pStr1;
#define pStr2  char*;
pStr1  s1,s2;
pStr2  s3,s4; 

上面示例中,s1、s2、s3都被定义为char *,而s4则定义成了char,不是我们所预期的指针变量(相当于:char *s3,s4;)。根本原因就在于#define只是简单的字符串替换而typedef则是为一个类型指定别名。

例如,

#include <iostream>
using namespace std;
 
#define TRUE  1
#define FALSE 0
typedef   char* pStr1;
#define pStr2  char*
pStr1  s1,s2;
pStr2  s3,s4; 
 
int main( )
{
   cout << "size of s1 is: " << sizeof(s1) << endl;//char* 类型     
   cout << "size of s2 is: " << sizeof(s2) << endl;//char* 类型   
   cout << "size of s3 is: " << sizeof(s3) << endl;//char* 类型  
   cout << "size of s4 is: " << sizeof(s4) << endl;//char类型  
   cout << "TRUE 的值: " << TRUE << endl;
   cout << "FALSE 的值: " << FALSE << endl;
 
   return 0;
}

注意:在C++中,typedef的这种用途二不是很大,但是理解了它,对掌握以前的旧代码还是有帮助的,毕竟我们在项目中有可能会遇到较早些年代遗留下来的代码。

推荐阅读
cjavapy编程之路首页