指针数组与数组指针
前言:
对于c语言初学者对这两个概念常常弄混,我当时刚学时,去看大佬博客,大佬们写的很多,强忍着看完了,觉得自己看懂了,接着就下一个知识点了,过了两天又忘了。。。编程的学习绝对是不能脱离实际的,实践是检验真理的唯一标准,所以检验自己到底会不会直接写代码检验一下是最好的(这里可不是让你背博客代码,也不是让你抄写,而是看会了之后用自己的方式实现一下,不看任何参考代码)。下面我将用代码的形式清晰的给你展示这两者的区别!
指针数组:
定义:类型 *名字[数组大小],如char *p[6];
首先看一下这个结构,看到有’[ ]'符号,这是一个数组你应该没有疑问,数组的元素是啥呢?是char *指针。你可以对比正常数组来看,如 int arr[6],这你肯定知道,这是一个大小为6的数组,数组里存储的元素类型为int类型。这样你再看 char *p[6],是不是就清晰多了。这是一个大小为6的数组,里面存储的是char *类型的指针,数组名字是p。ok,这回我们知道什么是指针数组了!啥你说你还不清楚!世上无难事,只要肯放弃,咱不学编程了!好的,既然你懂什么是指针数组,那么就和我一起来编程吧!
#include <stdio.h>
int main(int argc, char **argv)
{
//定义大小为6的指针数组,数组元素是char*
char *p[6];
//将第一个指针赋值为hello
p[0] = "hello";
printf("p[0] = %s\n", p[0]);
return 0;
}
我相信上面的代码你应该没有问题,给指针数组里的第一个指针赋值为“hello"。打印结果是hello。接下来我们继续学习
#include <stdio.h>
int main(int argc, char **argv)
{
char arr[2][6] = {"hello", "world"};
char *p[2];
//将二维数组的第一行赋值给指针数组的第一个指针
p[0] = arr[0];
//打印结果很明显是p[0] = hello
printf("p[0] = %s\n", p[0]);
//下面我们想打印指针数组的第二个指针指向的内容,结果是啥呢?是world?
//还是其它什么未知的内容
printf("p[1] = %s\n", p[1]);
//当你把上面的p[1]打出来的时候,发现是乱码的值,啥原因呢?
//你没给指针数组的第二个指针赋值啊,所以第二个指针指向内存一块未知的区域
//那么肯定是乱码啊,这里你可不要天真的认为,将二维数组的第一行数据赋值给指针数组的第一个数据,
//那么指针数组的第二个指针就默认指向二维数组的第二行数据。这个想法是错误的
p[1] = arr[1];
//这样打出来的结果才是p[1] = world;
printf("p[1] = %s\n", p[1]);
return 0;
}
我们换个赋值方式
#include <stdio.h>
int main(int argc, char **argv)
{
char arr[2][6] = {"hello", "world"};
char *p[6];
*p = *arr;
p[1] = arr[1];
printf("*p = %s\n", *p);
//打印结果是什么?比较容易,是*p = hello;
//思考一下,这个打印的结果是什么?
printf("*p+1 = %s\n", *p+1);
//结果是:*p+1 = ello, 是否是你心中的结果呢?下面来分析一下,为啥是这个结果!
//首先*p+1还是指针数组的第一个元素,啥你和我说是第二个? '*'的优先级是要高于'+'
//所以它其实应该长这样(*p)+1;这回清晰了吧,首先*p指向hello字符串,然后向后偏移了一个字符
//所以结果是ello
//思考一下,这个打印的结果是什么?
printf("*(p+1) = %s\n", *(p+1));
//没错就是*(p+1) = world!这回你可看好了哈,我将p+1用()给包起来了,所以先对指针数组进行
//偏移,然后再*,取该指针所指向的内容。
//大声说出来,下面打印的内容是啥!
printf("*(p+1)+2 = %s\n", *(p+1)+2);
//没错就是*(p+1)+2 = rld这个!
return 0;
}
学到这里我相信你对指针数组已经有了较深刻的理解了,那么现在自己实践一下!实践完成之后,接下来我们学习一下数组指针!
数组指针
定义:类型 ( *名字)[数组大小], 如:char ( *p)[10];
首先看结构,看到有’[ ]'符号,这是一个数组你应该没有疑问,数组的元素是啥呢?是char类型,p是指针,指向包含10个char元素的一维数组。
#include <stdio.h>
int main(int argc, char **argv)
{
char arr[2][6] = {"hello", "world"};
//需要注意的是,如果想用p指向二维数组,那么数值指针的大小要和二维数组的列大小要相同
//否则会出现存储不匹配,可以自行尝试
char (*p)[6];
//p指向arr[0], 这里也可以不进行类型转换,会报warning,但是不影响运行结果
p = (char(*)[6])arr;
//下面打印的结果是啥呢?
printf("*p = %s\n", *p);
//没错就是*p = hello
printf("*p+1 = %s\n", *p+1);
//打印结果: *p+1 = ello
printf("*(p+1) = %s\n", *(p+1));
//打印结果: *(p+1) = world
printf("*p[1] = %c\n", *p[1]);
//打印结果: *p[1] = w, p[1]指向二维数组的第二行的第一个元素,所以是w
//思考一下下面两个打印打印啥?
printf("*p[1]+2 = %c\n", *p[1]+2);
//打印结果:*p[1]+2 = y, *p[1]是w,那么'w'+2 不就是'y'么!wxyz
printf("*(p[1]+1) = %c\n", *(p[1]+1));
//打印结果: *(p[1]+1) = o, p[1]指向二维数组的第二行的第一个元素,那么p[1]+1
//不就是指向第二行的第二个元素了么!
return 0;
}
通过上面的代码我相信你肯定对数组指针有了较深刻的认识,就现在去用代码写一下吧!
总结
- 指针数组:本质上是数组,数组里面存储是指针
- 数组指针:本质上是指针,指针指向一个一维数组
本人能力有限,如有错误望各位大佬不吝指正,原创不易,转载请注明出处!