目录
小挑战
1.利用指针输出数组a[] ={1,2,3,4,5}中的每个元素
2.用指针数组打印多个数组int a[]={1,2,3,4}; int b[]={4,5,6,7}; int c[]={6,7,8,9};
3.用两种以上的指针方法打印二维数组int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
感觉如何,可以完成吗友友,不妨先看看我的理解。(答案附在文末)
地址的概念及理解
一维数组中:
假设一个一维数组a,那么数组名a即为数组的地址即为首元素地址(即值相等)用符号表示则为:
a = &a =&a[0]
二维数组中:
int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12}
那么类似地,数组名与数组首元素地址与数组地址相等。即:
&a = &a[0][0] = a
虽然值相等,但其类型并不相同。其中,&a 表示的是整个数组,&a[0][0]表示的是元素,而a则表示的是行指针。
既然值相等,那么类型不同又有什么意义呢?实际上,做过开头小挑战的同学会发现,其类型不同会带来的加减运算的结果不同,而这个是非常关键的。
比如说,a + 1,表示下一行的指针,而 &a[0]+1则表示这一行下一个元素的指针。也就是说,前者数值是&a[1][0],而后者的值是&a[0][1]。
*的概念及理解
概念:
当已具有一个指针,并且希望获取它所引用的对象时,使用间接运算符 *。
一维数组中:
*a是a[0],就是首个元素。
二维数组中:
a是行指针,获取它所引用的对象,所以*a是行的首元素地址。
故我们说*a和&a[0][0]的类型才真正相同。
故*a+1和a+1完全不同。
如何新建一个指针来代替数组名?
一维数组中:
#include <stdio.h>//指针变量赋初值
int main()
{
int a=3;
int *p=&a;//这里不是把a的地址赋值给了*p,而是定义了一个指针p,把a的地址赋值给了p,可以类比一下int s=3;
return 0;
}
#include <stdio.h>//指针变量赋初值
int main()
{
int a=3,*p;//int指针指向整型空间
p = &a;//这里不是把a的地址赋值给了*p,而是定义了一个指针p,把a的地址赋值给了p,可以类比一下int s=3;
return 0;
}
二维数组中:
int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
int (*p)[4]=a;
这里要注意,因为我们是创建了一个指针p,所以要让*p的优先级高,于是用括号括起来。
而int* p[4]的意思则是创建了一个数组 ,数组内部存放指针。
我们可以将两者用数组指针和指针数组来区分。
小挑战答案
(按顺序)
1.
//指针移动 利用指针输出数组中的每个元素
#include<stdio.h>
int main()
{
int i,len,*q;
int a[] ={1,2,3,4,5};
int *p = &a[0];
len = sizeof(a)/sizeof(a[0]);
for (i=0;i<len;i++)
printf("%d",*(p+i));
q=&a[len-1];
printf("%d",q-p);//计算得到的结果是指针的偏移量而非指针地址数值的大小相减
return 0;
}
2.
//用指针打印多个数组
#include <stdio.h>
int main()
{
int i,j;
int a[]={1,2,3,4};
int b[]={4,5,6,7};
int c[]={6,7,8,9};
int * d[]={a,b,c};
for (i=0;i<3;i++)
for (j=0;j<4;j++)
printf("%d",*(*(d+i)+j));
return 0;
}
3.for循环里两个语句代表 两种方法
#include<stdio.h>
int main()
{
int i,j;
int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
int (*p)[4]=a;
for (i=0;i<3;i++)
{
for (j=0;j<4;j++)
/*printf("%d",*((*p+j)+i*4));*///一行行输出
printf("%d",*(*(p+i)+j));
}
return 0;
}
写在最后:
大家一定要自己码一遍哦,还有不理解的可以在评论区里问或私信我,指针是c语言关键,一定要牢牢掌握。如果小挑战有要完整版解析的,可以在评论区留言,我看看共性问题的话再发一篇文章专门解析哈。