C++中的几个疑惑

typedef 关键字wiki

在C和C++编程语言中,typedef是一个关键字。它用来对一个数据类型取一个别名,目的是为了使源代码更易于阅读和理解。它通常用于简化声明复杂的类型组成的结构 ,但它也常常在各种长度的整数数据类型中看到,例如size_t和time_t。

typedef的语法是 :

1
typedef typedeclaration;

和结构体一起使用

1
2
3
4
5
typedef struct Node Node;
struct Node {
int data;
Node *nextptr;
};

和指针一起使用

1
2
3
4
5
6
7
typedef int *intptr;

intptr cliff, allen; // both cliff and allen are int* type

intptr cliff2, *allen2; // cliff2 is int* type, but allen2 is int** type
// same as: intptr cliff2;
// intptr *allen2;

和结构体指针一起使用

1
2
3
4
5
typedef struct Node Node;
struct Node {
int data;
Node *nextptr;
};

和函数指针一起使用

先来看这段没有使用typedef的代码:

1
2
3
4
5
6
7
8
9
10
int do_math(float arg1, int arg2) {
return arg2;
}

int call_a_func(int (*call_this)(float, int)) {
int output = call_this(5.5, 7);
return output;
}

int final_result = call_a_func(&do_math);

注意:这里的call_this是指向参数类型为(float, int) ,返回值是int类型的函数指针,另外注意函数指针的用法,

使用typedef后这段代码可以改写为:

1
2
3
4
5
6
7
8
9
10
11
12
typedef int (*MathFunc)(float, int);

int do_math(float arg1, int arg2) {
return arg2;
}

int call_a_func(MathFunc call_this) {
int output = call_this(5.5, 7);
return output;
}

int final_result = call_a_func(&do_math);

前加一个typedef关键字,这样就定义一个名为MathFunc的函数指针类型,而不是一个MathFunc变量。

函数指针的几个疑惑

问题:c语言中, 函数名也称为函数的指针,那函数名是否也占内存空间?

首先你上面的话是错误的,函数名是一段指令的入口地址,它是地址常量,不占用内存空间,只是在编译阶段存在于编译器的符号表中,例如函数的入口地址是0x123456,在翻译成机器指令以后,函数名是不存在的其在本质上对应汇编上的jump指令,在执行函数的时候,跳转到0x123456,这个函数名的本质就是这个地址。

c语言中其他变量的原理也都是类似的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
using namespace std;
typedef int (*funcptr)(int, int);
int add(int a,int b){
return a+b;
}
int test(funcptr ptr,int x, int y){
cout<<"this is a test";
return ptr(x, y);
}
int main(){
cout<<test(add,2,3)<<endl;
cout<<test(&add,3,4)<<endl;
cout<<&main;
return 0;
}

1)其实,MyFun的函数名与FunP函数指针都是一样的,即都是函数指针。MyFun函数名是一个函数指针常量,而FunP是一个函数数指针变量,这是它们的关系。

2)但函数名调用如果都得如(*MyFun)(10)这样,那书写与读起来都是不方便和不习惯的。所以C语言的设计者们才会设计成又可允许MyFun(10)这种形式地调用(这样方便多了并与数学中的函数形式一样,不是吗?)。

3)为统一起见,FunP函数指针变量也可以FunP(10)的形式来调用。

4)赋值时,即可FunP = &MyFun形式,也可FunP = MyFun。

C++迭代器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <vector>
#include <iostream>
using namespace std;

int main(){
vector<int> v1;
for(int i=0;i<100;i++){
if(i%3 ==0)
v1.push_back(i);
}
vector<int>::iterator it;
for(vector<int>::iterator it=v1.begin(); it != v1.end();it++){
*it += 2;
cout<<*it<<endl;

}
return 0;
}

注意迭代器的用法

::不要丢掉,否则语法错误;迭代器的本质是指针,指针在使用之前一定要赋值

小知识

  1. c语言print()函数的参数
    1. %d ——–dicimal(base 10)
    2. %x ——–hexadecimat(base 16)
    3. %o ——–octal(base 8)