在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
引言初入c++,肯定会对指针这个概念非常熟悉。但是为什么c/c++要使用指针? 其实每一种编程语言都使用指针,指针并不只是C/C++的独有特性。C++将指针暴露给了用户(程序员),而Java和C#等语言则将指针隐藏起来了。不光如此,指针还有很多妙用,后面会着重展开详解。 一,指针(*)的概念分析指针是一个变量,其值为另一个变量的地址,即,内存位置的直接地址。就像其他变量或常量一样,您必须在使用指针存储其他变量地址之前,对其进行声明。指针变量声明的一般形式为: 指针的类型 *指针变量的名称; 要搞清一个指针需要搞清指针的四方面的内容:
相关链接:一文让你不再害怕指针之C指针详解(经典,非常详细) - 知乎 (zhihu.com) 指针的类型(即指针本身的类型)和指针所指向的类型是两个概念。必须加以区分!!! 首先,先来看几个复杂类型的指针声明(有难入易更容易理解)int p; //这是一个普通的整型变量 int *p; //首先从P 处开始,先与*结合,所以说明P 是一个指针,然后再与int 结合,说明指针所指向的内容的类型为int 型.所以P是一个返回整型数据的指针 int p[3]; //首先从P 处开始,先与[]结合,说明P 是一个数组,然后与int 结合,说明数组里的元素是整型的,所以P 是一个由整型数据组成的数组 int *p[3]; //首先从P 处开始,先与[]结合,因为其优先级比*高,所以P 是一个数组,然后再与*结合,说明数组里的元素是指针类型,然后再与int 结合,说明指针所指向的内容的类型是整型的,所以P 是一个由返回整型数据的指针所组成的数组 int (*p)[3]; //首先从P 处开始,先与*结合,说明P 是一个指针然后再与[]结合(与"()"这步可以忽略,只是为了改变优先级),说明指针所指向的内容是一个数组,然后再与int 结合,说明数组里的元素是整型的.所以P 是一个指向由整型数据组成的数组的指针 int **p; //首先从P 开始,先与*结合,说是P 是一个指针,然后再与*结合,说明指针所指向的元素是指针,然后再与int 结合,说明该指针所指向的元素是整型数据.由于二级指针以及更高级的指针极少用在复杂的类型中,所以后面更复杂的类型我们就不考虑多级指针了,最多只考虑一级指针. int p(int); //从P 处起,先与()结合,说明P 是一个函数,然后进入()里分析,说明该函数有一个整型变量的参数,然后再与外面的int 结合,说明函数的返回值是一个整型数据 Int (*p)(int); //从P 处开始,先与指针结合,说明P 是一个指针,然后与()结合,说明指针指向的是一个函数,然后再与()里的int 结合,说明函数有一个int 型的参数,再与最外层的int 结合,说明函数的返回类型是整型,所以P 是一个指向有一个整型参数且返回类型为整型的函数的指针 二,指针的算术运算指针是一个用数值表示的地址。因此,您可以对指针执行算术运算。可以对指针进行四种算术运算:++、--、+、-。 假设 ptr 是一个指向地址 1000 的整型(int)指针,是一个 32 位的整数,让我们对该指针执行下列的算术运算: ptr++ 在执行完上述的运算之后,ptr 将指向位置 1004。如果 ptr 指向一个地址为 1000 的字符(char),上面的运算会导致指针指向位置 1001,因为下一个字符位置是在 1001。 因为int类型在32位程序中占4个字节,字符char类型占1个字节 递增一个指针 我们喜欢在程序中使用指针代替数组,因为变量指针可以递增,而数组不能递增,因为数组是一个常量指针。下面的程序: 例如,一个指向数组开头的指针,可以通过使用指针的算术运算或数组索引来访问数组。请看下面的程序:(递增变量指针(ptr++),以便顺序访问数组中的每一个元素) #include <iostream> using namespace std; const int MAX = 3; int main() { int var[MAX] = { 10, 100, 200 }; int* ptr; // 指针中的数组地址(指针指向数组开头) ptr = var; for (int i = 0; i < MAX; i++) { cout << "Address of var[" << i << "] = "; cout << ptr << endl; cout << "Value of var[" << i << "] = "; cout << *ptr << endl; // 移动到下一个位置 ptr++; } return 0; } 三,运算符&和*C++ 提供了两种指针运算符
int main () { int var = 3000; int *ptr; int val; // 获取 var 的地址 // 获取 ptr 的值 }
四,数组和指针的关系数组的数组名其实可以看作一个指针。看下例: int array[10]={0,1,2,3,4,5,6,7,8,9},value; ... ... value=array[0];//也可写成:value=*array; value=array[3];//也可写成:value=*(array+3); value=array[4];//也可写成:value=*(array+4); 上例中,一般而言数组名array代表数组本身,类型是int [10],但如果把array看做指针的话,它指向数组的第0个单元,类型是int *,所指向的类型是数组单元的类型即int。因此*array等于0就一点也不奇怪了。同理,array+3是一个指向数组第3个单元的指针,所以*(array+3)等于3。其它依此类推。 五,指针和结构类型的关系可以声明一个指向结构类型对象的指针。 struct MyStruct { int a; int b; int c; } MyStruct ss={20,30,40};//声明了结构对象ss,并把ss的三个成员初始化为20,30和40。 MyStruct *ptr=&ss;//声明了一个指向结构对象ss的指针。它的类型是MyStruct*,它指向的类型是MyStruct。 怎样通过指针ptr来访问ss的三个成员变量? ptr->a; ptr->b; ptr->c; 六,传递指针给函数C++ 允许传递指针给函数,只需要简单地声明函数参数为指针类型即可。 下面的实例中,我们传递一个无符号的 long 型指针给函数,并在函数内改变这个值: #include <iostream> #include <ctime> using namespace std; // 在写函数时应习惯性的先声明函数,然后在定义函数 //定义一个函数(参数为指针) void getSeconds(unsigned long* par); int main() { unsigned long sec; getSeconds(&sec);//获取sec的地址 // 输出实际值 cout << "Number of seconds :" << sec << endl; return 0; } void getSeconds(unsigned long* par) { // 获取当前的秒数 *par = time(NULL); return; } 七,从函数返回指针C++中函数是不能直接返回一个数组的,但是数组其实就是指针,所以可以让函数返回指针来实现: 另外,C++ 不支持在函数外返回局部变量的地址,除非定义局部变量为 static 变量。 要想返回一个数组,使用智能指针之类的东西才是正途。(后续总结智能指针。。。)
|
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论