知乎上有个关于指针的问题:为什么说指针是C语言的精髓?答案五花八门,今天来加深对指针的理解。
首先要知道指针的概念,在百科上, 在计算机科学中, 指针 (Pointer)是编程语言中的一个对象,利用地址,它的值直接指向(points to)存在电脑存储器中另一个地方的值。学习任何东西,明确概念是非常重要的,指针首先是个对象,与类(class)、结构体(struct)、整数变量(int)都是一样的。指针是一个变量,具有变量的特性,变量要存放在内存中,变量有值。它的值存储着存储器的一个地址,那么指针在内存中占用的空间应该是一样的,因为它存放的是地址,而地址的长度是不变的。无论这个指针指向的地址类型是怎样的,如整数指针、字符指针、结构体指针、类指针、函数指针,它占用的内存都是相同的。写个程序使用sizeof验证。
#include <bits/stdc++.h>
using namespace std;
struct structA {
int member1;
int member2;
};
class classB {
int member1;
char member2;
};
int main(){
int* int_ptr;
char* char_ptr;
structA* struct_ptr;
classB* class_ptr;
cout << "sizeof(int_ptr) = " << sizeof(int_ptr) << endl;
cout << "sizeof(char_ptr) = " << sizeof(char_ptr) << endl;
cout << "sizeof(struct_ptr) = " << sizeof(struct_ptr) << endl;
cout << "sizeof(class_ptr) = " << sizeof(class_ptr) << endl;
return 0;
}
输出结果如下:
sizeof(int_ptr) = 8
sizeof(char_ptr) = 8
sizeof(struct_ptr) = 8
sizeof(class_ptr) = 8
我的计算机是64位的,地址长度是64位,所以一个指针变量占8个字节。
有了以上这些解释后,指针的内容也就是这些。
但是,有些人见到指针就害怕,不敢在程序中使用指针,没有发挥指针的优势。下面讨论一些指针的误区和使用。
1,数组名实质上是指针?
以前听到过这样一句话“数组名实质上是指针”,验证这句话是否正确,用事实说话就可以了,使用sizeof打印数组名,看长度是否等于地址长度,然后打印数组名,值是否是地址。
#include <bits/stdc++.h>
using namespace std;
int main(){
int a[3] = {1,2,3};
cout << "sizeof(a) = " << sizeof(a) << endl;
cout << "a = " << a << endl;
char s[3] = "ab";
cout << "sizeof(s) = " << sizeof(s) << endl;
cout << "s = " << s << endl;
return 0;
}
结果:
sizeof(a) = 12
a = 0x22fe40
sizeof(s) = 3
s = ab
表明数组名不是一个指针,因为sizeof打印的长度并不是地址的长度。而打印字符数组名的时候,不是地址,而是打印字符数组的数据。第二行打印内容整数数组名a,确实是一个地址。但是它不是一个指针,数组名代表一个数组,由它可以求出数组类型,数组大小等,但它本质上不是指针。
2,指针的声明
假如声明一个int类型的指针
int* a_ptr; // 1
int *b_ptr; // 2
两种方式都是正确的,不过我更提倡采用第1种方式。这样方便理解,ptr的类型是int*,第2种更让人以为*b_ptr的类型是int,这样说是没错的,使用“*”取指针指向的地址的值,但是第1种更突出a_ptr是一个变量。
函数指针的声明,在很多优秀的开源代码中经常会碰到函数指针。
例如 int (*func)(int, int);
函数指针名是func,它指向的函数有两个参数,都是int,返回值也是int。注意一定要加括号,(*func),不然就是声明一个指针函数。
有一个函数
int max(int a, int b){
return a > b ? a : b;
}
声明一个函数指针func后,就可以使用了。
func = max; //表明函数指针func指向函数名为max的函数。
当然你也可以这样做来赋值,和上面的方式没有区别。
func = &max; //将函数max的地址给指针func。
(*func)(2,3); //使用函数指针。
我们前面提过,使用“*”来取指针指向的地址的值,现在*func就表明取func指向的“max函数”,取的值是一个“函数对象”。
func(2,3); //使用函数指针。
这种方式也可以得到正确的结果,为什么这样也正确?
下面这段话摘自《C++ prime plus》:
3,函数指针和指针函数的区别
“函数指针”,函数修饰指针,本质上是个指针。
“指针函数”,指针修饰函数,表示函数的返回值是个指针类型的变量。