本篇是对字符指针、数组指针、指针数组这篇博客进行的补充。
字符指针、数组指针、指针数组以及指针传参——C语言
上一篇博客对字符串常量的介绍较为笼统与模糊,以及对“二维数组”根本没有介绍。
本篇将重点整理数组与指针的关系以及一些便于记忆的代码。
2.字符串常量我们先研究一段代码:
#include
int main()
{
char* str = "abcd";
char arr[] = "abcd";
if (str == arr)
printf("1\n");
else
printf("0\n");
return 0;
}
输出结果:
这段代码我们介绍过,但是并没有给出很明确的解释。
现在我们来详细分析:
我们用 if else 语句来判断 str 和 arr 的地址是否相同,输出结果为 0 ,即不相同。
我们的问题在于,都使用看起来相同的字符串,为什么地址会不相同。
首先看 char* str = "abcd" ; 这条语句:
我们再看 char arr[] = "abcd" ; 这条语句:
3.数组与指针事实上,在C语言中,只存在一维数组。不是有二维数组吗?这个问题在后面解释。
我们先来看一段代码:
#include
int main()
{
char arr1[5] = "abcd";
char arr2[5] = "abcd";
//都是把第二个元素改为'B
arr1[1] = 'B';
*(arr2 + 1) = 'B';
printf("%s\n", arr1);
printf("%s\n", arr2);
return 0;
}
输出结果:
这个例子很好的将 指针 和 数组 联系起来。
实际上,我们对数组的 *** 作只有两种:
一是确定数组的大小。
二是获得首元素的地址。
这就很奇怪了,我们明明使用数组的下标改掉数组的内容了啊!
其实,除了对数组 *** 作的两种方法外,我们想要 *** 作数组,只能使用指针,就算看起来使用的是数组下标,实际上它也是一种指针 *** 作。只不过数组下标是指针 *** 作的简写,被常用而已。
我们再来研究下面这串代码:
#include
int main()
{
char str[5] = "abcd";
char* ps = str;
printf("%p\n",str);
printf("%p\n",ps);
printf("%p\n", &str[0]);
return 0;
}
运行结果:
可以看见打印出的地址一摸一样。
由此我们得出结论:对于数组来说,在本该出现指针的地方,使用了数组名,那么数组名就被当作首元素地址。
现在我们可以来谈谈 “二维数组” 了。
我们来考虑这段代码:
#include
int main()
{
int arr[10][20];
return 0;
}
我们来试着理解 int arr[10][20]; 是什么意思:
现在理解了 “二维数组” ,现在有一个问题:所有情况下数组名都是首元素地址吗?
我们来看一段代码:
#include
int main()
{
int arr[2][3] = { 1,2,3,2,3,4 };
printf("%d\n", sizeof(arr));
return 0;
}
我们使用 *** 作符 sizeof 计算数组的大小,可见 arr 并不是一个地址。
所以这里有一个特例:如果数组名不是用在sizeof下,那么数组名就是首元素地址。
我们理解了二维数组,那我们想办法来 *** 作它。
我们有 int arr[2][3] = {1,2,3,2,3,4}; ,那我们想输出第二个3,应该如何做?
#include
int main()
{
int arr[2][3] = { 1,2,3,2,3,4 };
printf("%d\n", *(*(arr + 1) + 1));
printf("%d\n", arr[1][1]);
return 0;
}
现在就能输出第二个3了。
由此也可见,当我们使用数组下标,在一定程度上可以简化代码。
4.数组与函数参数我们来看我们经常使用但是又经常忽略的一种函数传参方式。
#include
int main()
{
char str[] = "abcd";
printf("%s\n", str);
printf("%s\n", &str[0]);
return 0;
}
我们要记得,我们把数组名 str 传给了 printf 函数,也就是把数组的首元素地址给了 printf 函数。
%s 它会自己顺着这个地址往后找,直到找到 '数组作为函数参数是毫无意义的。' 。
所以屏幕上会出现:
因为我们数组名作为参数传参被转化成数组首元素地址,所以, 实际上 print1 和 print2 毫无差别,上面说过数组作为函数参数是毫无意义的,所以,print1的参数会自动转换为指针。
我们来谈谈二维数组的传参:
#include
void print2(int (*arr)[3])
{
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
printf("%d ", *(*(arr+i)+j));
}
printf("\n");
}
}
void print1(int arr[2][3])
{
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
printf("%d ", arr[i][j]);
}
printf("\n");
}
}
int main()
{
int arr[2][3] = { 1,2,3,2,3,4 };
print1(arr);
printf("\n");
print2(arr);
return 0;
}
输出结果:
可以看到 print1 和 print2 的效果一样。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)