关于指针的有关问题,p和*p,实在没有理解,求教

关于指针的问题,*p和**p,实在没有理解,求教!
有两段代码,都是正确的,如下:
NO.1 
main(){
int x,*p,**pp;
x=10;
p=&x;
pp=&p;
printf("x=%d\n",**pp);

NO.2

main(){
static char *ps[]={ "BASIC","DBASE","C","FORTRAN",
"PASCAL"};
char **pps;
int i;
for(i=0;i<5;i++){
pps=ps+i;
printf("%s\n",*pps);
}
}
l两段代码中最后一句分别用了**pp和*pps,明显意义不同,为何输出却又是正确的,我自己在分别修改**pp为*pp和*pps为**pps之后没有得到合理结果,求知道的解释下,万分感激!

------解决方案--------------------
1 我自己在分别修改**pp为*pp

*pp是什么,这是个指针,printf("x=%d\n",*pp);  %d将指针的内容打印出来了,这个指针的内容是指向x的地址的

2 和*pps为**pps之后没有得到合理结果,求知道的解释下,万分感激!

**pps是什么,是字符,printf("%s\n",**pps); %s是将字符串打印出来,而你传给print的是字符,结果是什么,oh no......... access violation
------解决方案--------------------
引用:
有两段代码,都是正确的,如下:
NO.1 
main(){
int x,*p,**pp;
x=10;
p=&x;
pp=&p;
printf("x=%d\n",**pp);

NO.2

main(){
static char *ps[]={ "BASIC","DBASE","C","FORTRAN",
"PASCAL"};
char **pps;
int i;
for(i=0;i<5;i++){
pps=ps+i;
printf("%s\n",*pps);
}
}
l两段代码中最后一句分别用了**pp和*pps,明显意义不同,为何输出却又是正确的,我自己在分别修改**pp为*pp和*pps为**pps之后没有得到合理结果,求知道的解释下,万分感激!

NO1
pp = &p;
p = & x;
int x = 10;

** pp = **(&p) = *p = *&x = x
而将 **pp 改为 *p后
*pp = *(&p) = p = &x != x

NO 2
char **pps
pps =  ps + i
*pps = *(ps + i) = ps[i],即字符串二维数组当中的每个字符串的首地址,用%s输出,则是相应的字符串
**pps = **(ps + i) = *(ps[i])
而ps[i] = &ps[i][0]
所以*(ps[i]) = *(&ps[i][0]) = ps[i][0]
ps[i][0]是个字母,后面没跟'\0',但用%s输出,因此结果不可预测。
------解决方案--------------------
引用:
1 我自己在分别修改**pp为*pp

*pp是什么,这是个指针,printf("x=%d\n",*pp);  %d将指针的内容打印出来了,这个指针的内容是指向x的地址的

2 和*pps为**pps之后没有得到合理结果,求知道的解释下,万分感激!

**pps是什么,是字符,printf("%s\n",**pps); %s是将字符串打印出来,而你传给print的是字符,结果是什么,oh no......... access violation
有个问题,想要打印一个地址的类容使用%p,而不是%d