Lickoo的小本本
Lickoo的小本本

老李のC++指针复习笔记

老李のC++指针复习笔记

用处、如何定义?

创建数据结构、动态分配内存、拦截软件进程等。

定义方法:type *var-name; 值得注意的是,在定义时*的位置可以贴在type处,效果是一样的,为了方便理解,我们下面将所有的定义都贴在type处

例如:

int* a; //等价于int *a;
char* c = NULL;
double* dd = # //此处的num为事先声明好的double类型变量
struct node* newNode; //结构体类型的指针

& 取地址符号

作用:用来得到某个数据所存放的地址。

示例:

#include <iostream>
using namespace std;

int main()
{
 int a = 0;
 char c;
 cout << &a << endl << &c << endl;
 return 0;
}

* 解引用符号

作用:解析地址对应的数据

示例:

#include <iostream>
using namespace std;

int main()
{
 int a = 0;
 int* p = &a;  //注意,此处的*为声明int类型指针变量的符号,不是解引用符号
 *p = 1;  //此处的*也为解引用
 cout << *p << endl;  //此处的*为解引用符号
 return 0;
}

重要的概念

  • 在此,可以不严谨地认为指针=地址
  • 指针变量是用来存放指针的变量,不能存放其他数据类型。比如用&对某个变量取值之后得到它的地址,才可以进行存放。
  • 要注意的是,比如指针也是有类型的,比如int类型的指针变量只能存储int数据类型的地址,而不能存储char类型的地址,因为不同的数据类型所占的内存大小是不一样的。
  • 解引用*可以认为是指针指向的地址的位置向后面几个位连起来读值

空指针NULL

要是我没记错的话,在iostream这个头文件里面有定义#define NULL 0

因此有一个简单的用法,可以用来检测指针是否为空

if (ptr){}
//此处的ptr为一个指针,可以通过指针是否为空来执行if语句

指针的运算 ++ — + –

  • 指针++表示向下移动一个内存位置,比如一个int为4字节,一个int类型的指针的值++一次就自增32(一字节是8位),指向的内存位置往后挪动32位。同理,一个char类型的指针++一次就往后挪8位
  • –和++为相反操作,不多赘述

+和-即为向前挪动或向后挪动若干个单位,例如:

#include <iostream>
using namespace std;

int main()
{
 int var[3] = {1,2,3};
 int* ptr = var;
 ptr + 2;
 cout << *ptr << endl;
 return 0;
}
#include <>iostream>
using namespace std;

int main()
{
 int* ptr = NULL;  //声明指针的时候给它赋空值是个好习惯
 int var[3] = {100,200,300};
 ptr = var;  //数组名就是一个地址,指向数组的首地址,是一个常量
 cout << *ptr << endl;
 cout << ptr << endl;
 ptr++;
 cout << *ptr << endl;
 cout << ptr << endl;
 ptr++;
 cout << *ptr << endl;
 cout << ptr << endl;
 ptr++;
 cout << *ptr << endl;
 cout << ptr << endl;
 ptr--;
 cout << *ptr << endl;
 cout << ptr << endl;
 endl;
}

指针的比较

众所周知,地址是16进制的值,既然是值就可以进行比较

符号:> < ==

示例程序(遍历数组):

#include <iostream>
using namespace std;
#define max 4

int main()
{
 int var[max] = {1,2,3,4};
 int* ptr = var;
 while(ptr <= &var[max - 1])  //数组的取值范围为0~3,此处应-1
 {
 cout << *ptr << endl;
 ptr++;
 }
 return 0;
}

指针访问数组

如前所述,数组名为数组的首地址,故可以通过指针对数组进行操作

需要注意的是,数组名是一个地址常量,不可进行++、–运算,但是可以进行+、-运算

示例代码:

#include <iostream>
using namespace std;

int main()
{
 int var[4];
 int* ptr = var;
 *ptr = 1;
 *(ptr + 1) = 2;
 *(ptr + 2) = 3;
 *(ptr + 3) = 4;  // *(ptr + 3) = 4;  //用指针对数组进行赋值
 while(ptr <= (ptr + 3))
 {
 cout << *ptr << endl;
 ptr++;
 } //用指针遍历数组
 return 0;
}

需要注意的是,数组名是一个地址常量,不可进行++、–运算,但是可以进行+、-运算

#include <iostream>
using namespace std;
const int MAX = 3;

int main ()
{
 int  var[MAX] = {10, 100, 200};
 for (int i = 0; i < MAX; i++)
 {
 *var = i;    // 这是正确的语法
 var++;       // 这是不正确的

双重指针

简单地说,双重指针甚至多重指针就是对指针的操作进行套娃

示例代码:

#include <iostream>
using namespace std;

int main ()
{
 int  var;
 int  *ptr;
 int  **pptr;
 var = 3000;
 // 获取 var 的地址
 ptr = &var;
 // 使用运算符 & 获取 ptr 的地址
 pptr = &ptr;
 // 使用 pptr 获取值
 cout << "var 值为 :" << var << endl;
 cout << "*ptr 值为:" << *ptr << endl;
 cout << "**pptr 值为:" << **pptr << endl;
 return 0;
}

运行结果:

var 值为 :3000
*ptr 值为:3000
**pptr 值为:3000

传递指针给函数

我们都知道,给一个函数传递普通数据类型的形参时,系统会在内存中开辟一段临时的空间,用来存放拷贝过来的数据,在函数内运算之后进行销毁,这就意味着实参(即被拷贝的源数据)并不会发生改变

使用指针来进行函数操作,在函数内部操作的数据即为指针指向的数据,即会修改函数之外的数据

示例代码:

#include <iostream>
#include <ctime>
usng namespace std;

void getsecond(unsigned long* s)
{
 *s = time(NULL);  //使用解引用对指针指向的值进行修改
 return;
}

int main()

{
 unsigned long sec;
 getSeconds(&sec);  //传参,将sec的地址传入
 while(1)
 cout << "当前的秒数:" << sec << endl;
 return 0;
}

传递数组指针给函数:

示例代码:

#include <iostream>
using namespace std;

double get_avg(int* arr,int size)
{
 int temp = size;
 int sum = 0;
 while(size > 0)
 sum += *(arr + size);
 return sum / temp;
}

int main()
{
 int[5] = {1,2,3,4,5};

 cout << get_avg(&test,5);
 return 0;
}

函数返回指针

C++不支持返回函数内局部变量的地址到函数外,除非定义为static或者new到堆区

示例代码:

#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;

int* GetRandom()

{
 static r[10];
 srand((unsigned)time(NULL));  //设置时间为种子
 for(int i = 0;i < 10;i++)  //此处的i++和++i对程序是否有影响?
 r[i] = rand();
 return r;
}

int main()
{
 int* p = NULL;
 p = GetRandom();
 for(int i = 0;i < 10;i++)
 cout << "*(p + " << i << "):" << *(p + i) << endl;
 return 0;
}

Lickoo的小本本

老李のC++指针复习笔记
用处、如何定义? 创建数据结构、动态分配内存、拦截软件进程等。 定义方法:type *var-name; 值得注意的是,在定义时*的位置可以贴在type处,效果是一样的,为了方便理解,我们下…
扫描二维码继续阅读
2022-03-03
--> <-- mouse effects show end -->