可爱的指针(二)

可爱的指针(二)

在上一篇可爱的指针(一)中,我们了解了指针的基本内容。在这一篇中,我们主要了解指针与字符串、二维数组之间的操作。

字符串和指针

在具体讲字符串和指针之间的操作以前,我们首先回顾一下字符串。在C\C++中(抛开字符串string类),字符串是结尾为\0的一个字符数组。比如,我们可以用一下几个方式定义并初始化字符串:

char A[8] = "Beijing";
char B[] = "Beijing";
char c[10] = "include"; //虽然定义了长度为10的字符数组,但实际上最后3位均为‘\0’

分析以下程序:

#include
using namespace std;
int main(){
  char h[] = "Peking";
  h[0] = 'a'; h[1] = 'b';
  h[2] = 'c'; h[3] = '7';
  h[4] = 'c';
  cout<

此程序的逻辑不难,主要的核心就是替换h[0]h[4]最后程序会打印出abc7cg。有意思的地方在cout<。之前我们提到数组名字等价于指向这个数组的指针(数组第一个元素的地址),但是使用cout语句却没有打印出地址,而是字符串的内容(直到找到\0)。这就是cout对字符数组特殊的处理

简单介绍过字符串之后,我们来看看指向字符串的指针。其实和常规数组的指针一样,指向字符串的指针变量可以这样定义:char a[10]; char *p; p = a;

Example 1

int main(){
  char a[] = "How are you?", b[20];
  char *p1, *p2;
  for(p1 = a, p2 = b; *p1 != '\0'; p1++, p2++)
    *p2 = *p1;
  *p2 = '\0';
  cout<<"string a is: "<

这个程序的核心在*p2 = *p1;,即把所有a字符串的内容赋值给b。所以程序会打印出:

string a is: How are you?
string b is: How are you?

Example 2

int main(){
  char buffer[10] = "ABC";
  char *pc;
  pc = "hello";
  cout<

这段程序主要考察使用cout输出指向字符串的指针。cout<可以直接打印出hello,在pc++之后,指针指向字符'e',所以再打印pc会输出ello。对于cout<<*pc<,只会打印单独的字符e,因为*pc此时等价于hello中第二个字符(数组的名字是指向数组的第一个元素的指针,在pc自增后,指向第二个元素)。pc = buffer;意味着我们可以将另一个字符串指针赋值给pc,因为pc是指针变量,可以进行更新。综上,程序的运行结果是:

hello
ello
e
ABC

二维数组与指针

之前我们提到的指针与数组(无论是普通数组还是字符数组),都是考虑的一维的情况。在指针指向一维数组的情况时,指向数组的指针等价于指向数组第一个元素的指针。当指针指向二维数组时,这个规律依旧成立。我们先回顾一下二维数组的相关概念。

  • 定义二维数组:int a[3][4],表示定义了三个存放a[4]型数据的存储单元。他们的名字分别为a[0], a[1], a[2]
  • 二维数组a[3][4]包含三个元素:a[0], a[1], a[2]。每个元素都是一个“包含四个整型元素”的数组。

[图片上传失败...(image-66b17d-1606053716702)]
这里,二维数组a[3][4]中的a代表指向第一个元素a[0]的指针(注意这里的表述,虽然指向a[0]的指针和指向a[0][0]的指针的值是相同的,但如果把这两个指针分别加一,指针变量的变化是不一样的)。

总结一下,定义一个二维数组:int a[3][4] = {{1,3,5,7}, {9,11,13,15}, {17,19,21,23}};

  • 由对一维数组的分析可知:数组名是指向数组第一个元素的指针。
  • 且二维数组的第一个元素是a[0]a[0]是一个包含四个整型元素的一维数组)。
  • 则可以做出判断:(1)a&a[0]等价;a[0]&a[0][0]等价;(2)a[0]*a等价;a[0][0]**a等价

乍一看可能有些晕。没关系,我们先看一下一维数组的情况,然后通过一维数组扩展到二维数组。
给定一个一维数组int a[4] = {1,3,5,7};

  • a是指向数组第一个元素的指针,即a等价于&a[0]。如果我们将a自加1,则a会指向a[1],跨越4字节。
  • *a是数组的第一个元素a[0],即*a等价于a[0]。这里我们可以看出*a相当于“下沉”了一级。
  • &a是指向数组的指针,&a+1将跨越16字节。所以,&a相当于“上浮”了一级。

Example 3

#include
void main(){
  int a[4] = {1,3,5,7};
  cout<<"a = "<

这里,char *name[]就是一个指针数组。

指向指针的指针

前面提到我们可以用指针变量来存放地址,每一个变量也是对应一个地址。所以一定存在一个指针,它指向一个指针变量,我们可以把它看成指向指针的指针。在Example 6中,char *name是一个指针数组,它的每一个元素都是一个指针。如果我们想通过一个指针来访问每一个指针数组的元素,我们可以使用指向指针的指针char **p=name;。这里,p指向指针数组的第一个元素(为“Follow me”的指针)。

你可能感兴趣的:(可爱的指针(二))