数组和指针的运用,以及指针存储地址的过程

不知道怎么理解这一段代码的意思,最终运行的过程是什么来的

int main()
{
char* a [ ]  =  {"abc","def","ghi"};
char**pa=a;
pa++;
printf("%s\n", *pa);
return 0;
}

供参考:

#include <stdio.h>
int main()
{
    char* a[] = {"abc","def","ghi"};// 定义了一个指针数组 a[3], 这个数组有三个元素a[0] a[1] a[2],
                                    // 三个元素都是字符串指针,a[0] = "abc" ,a[1] = "def" , a[2] = "ghi"

    char**pa=a;   // (char*) *pa = (char*)a;   数组名就是指针 *pa = a

    pa++;  // pa 是数组a[3] 首地址 &a[0],pa++ ==> &a[1]

    printf("%s\n", *pa); // *pa = a[1] = "def", 所以输出:def

    return 0;
}

二维数组,可以看成是指针数组,也就是指向指针的指针。运行结果是将数组中三个元素(字符串)按行输出