【笔记】指针

c++ 一本通上在第一章就有指针讲解,但是当时老师跟我们说学这个东西没用,还会误导人,所以就直接略了过去 。

直到现在,在我 qbxt 七日游中,STL 中的 set 成功让我认识到了指针的重要性(不会没法用 set),因此特地在网上恶补一番,顺便做个笔记 。

定义指针类型

int *a = &b                  // 定义一个 int 类型的指针 a 并指向 int 类型的变量 b
double *a = &b               // 定义一个 double 类型的指针 a 并指向 double 类型的变量 b
Node *a = &b                 // 定义一个名称为 Node 的结构体类型的指针 a 并指向名称为 Node 的结构体类型的变量 b
int **a = &b                 // 定义一个 int 类型的指针 a 并指向 int 类型的指针 b
int (*a)[5] = &b             // 定义一个有 5 个 int 类型的数组指针 a 并指向一个有 5 个 int 类型的数组 b
int *a = b                   // 定义一个 int 类型的指针 a 并指向一个名称为 b 的 int 类型的数组的第一个元素
int (*a)(int, int) = b       // 定义一个返回类型为 int,有 2 个 int 形参的函数指针并指向函数 b(b 前可以加 &)
const char *a = "LKP AK IOI" // 定义一个 char 类型的常量指针 a 并指向一个元素为 "LKP AK IOI" 的字符数组
  1. 赋值号必须加(一定要赋值,不然会形成野指针导致程序出错)。

  2. 用取地址或者 NULL 来赋值 。

  3. 总之必须赋值

调用指针对象及修改

int b = 64;
int *a = &b;
printf("%d
", *a);
printf("%d
", b);
*a = 32;
printf("%d
", *a);
printf("%d
", b);

结果:

struct Node {
  int l, r;
  double tmp;
  char id[8];
};
Node b = (Node){1, 5, 62.4, "114514"};
Node *a = &b;
printf("%d %d %lf %s
", a -> l, a -> r, a -> tmp, a -> id);
printf("%d %d %lf %s
", b.l, b.r, b.tmp, b.id);
a -> l = 4;
a -> tmp = 23.3;
printf("%d %d %lf %s
", a -> l, a -> r, a -> tmp, a -> id);
printf("%d %d %lf %s
", b.l, b.r, b.tmp, b.id);

结果:

  1. 指针中可以通过修改指针(需加上 *,不加会 CE(不能修改地址))来修改原变量值 。

  2. 输出指针时加上 * 会输出指针所指变量值 。

  3. 输出指针时不加上 * 会输出指针所指变量地址 。

指针之间的赋值

直接赋值就行 。

int b = 64;
int *a = &b;
int *c = a;
printf("%d
", *a);
printf("%d
", b);
printf("%d
", *c);

结果:

  1. 定义的指针变量如果加 * 则整体为该指针所指的变量值 。

  2. 定义的指针变量如果不加 * 则整体为该指针所指的变量地址 。

  3. 取指针的地址直接用 &,不要再加上 *

  4. 用 1 号指针给 2 号指针赋值时,1 号指针不要加上 *

指针的隐藏要素

  1. 用指针去指向数组变量时,以及指向其他类型变量时,要使指针类型与被指向元素类型一致,不然会出问题(尽量不用强制转换) 。

  2. 强制转换方法:*(char*)a,将指针 (a) 转换为 char 类型 。

注意:强制转换时,指针本身的 * 要在强制类型前,强制类型后要加上 * 以示为指针 。

指针的加减

指针只能与常量进行加减,且与正常加减意义不同 。

通常指针的加减是在数组指针中进行的 。

int b[10] = {0, 1, 2, 3, 4, 5};
int *a = b;
printf("%d
", *a);
printf("%d
", *a + 1);
printf("%d
", *a + 2);
printf("%d
", *a + 3);
printf("%d
", *a + 4);

结果:

  1. 指针可以自增自减 。

  2. 指针加减的常数可以看做是数组中的位置 。

  3. 直接输出数组名会返回数组第一个元素的地址 。

  4. 直接输出数组名加某常数会返回从数组第一个元素开始第 sizeof(元素类型) * 该常数

函数中的指针

传参

void swap(int *a, int *b) {
  *a ^= *b ^= *a ^= *b;
}
int a = 96, b = 64;
swap(&a, &b);
printf("%d %d
", a, b);

结果:

用指针指向函数

int add(int a, int b) {
  return a + b;
}
int (*c)(int,int) = add; // add 前加不加 & 都一样
int a = c(1,2);	 	 // 可以当做函数名,c 前加不加 * 都一样

常量指针

指针本身是常量

int a = 97, b = 98;
int* const c = &a;
*c = 98;		// 改变了指针所指向的变量的值,正确
c = &b;		        // 改变指针所指地址,错误

指针指向常量

int a = 97, b = 98;       
const int* c = &a;      // 或写成 int const *c = &a;
c = &b;                 // 改变了指针所指地址,正确
*c = 98;		// 改变指针所指常量的值,错误
原文地址:https://www.cnblogs.com/EiffelA-blog/p/15044545.html