我在代码中四处闲逛,发现了这个:
这是代码:
#include "stdio.h"
void a_f(char str[][0]) /// !!! Если менять правый индекс то программа будет выводить адреса с интервалами которые равны индексу (сейчас это зафиксированно и указатель никак не меняется!)
{
int i = 4;
while(i >= 0)
{
printf("%s - %p\n", str+i, str+i);
--i;
}
}
int main(void)
{
char a[][10] = {"hello", "world", "again", "repeat", "stop"};
printf("start:%p\nend:%p\n\n", a, a+4);
a_f(a);
return 0;
}
我无法解释它是什么以及为什么?解释一下这是什么动物!我没有在有关数组的各种手册中看到这一点。
如果你有一个指向某种类型对象的指针,比如
为了能够使用此指针进行指针运算或取消引用指针,您需要知道指针指向的对象的大小。换句话说,您需要知道 的值
sizeof( T )
。例如,如果有一个表达式
++p
,那么问题来了:指针存储的值应该增加多少?显然,经过这个操作,指针必须指向内存中给定对象之后的地方(或者指向数组的下一个元素,如果当前对象是数组的元素),即指针的值必须增加 的值sizeof( obj )
。这意味着编译器必须知道指针指向的对象的大小。所以对于这个功能
使用声明为二维数组的参数调用
声明为数组的函数参数隐式转换为指向数组元素的指针。反过来,参数,即二维数组
a
,被隐式转换为指向其第一个元素的指针。这个二维数组的元素又是一个一维数组类型
char[10]
因此,如果你有一个指向这个二维数组第一个元素的指针,那么为了改变它,让它指向下一个,也就是说,数组的第二个元素,它的值必须增加寻址元素的大小。寻址元素(即一维数组)的大小为sizeof( char[10] )
. 该函数必须知道此可寻址数组的大小才能正确执行指针操作。所以函数的参数声明为
转换为类型
即,指向数组元素的指针。
反过来,作为函数参数给出的数组也被转换为指向其第一个元素的指针。这可以表示如下
sizeof( char[10]
有了关于声明为函数参数的 char ( *str )[10]) 指针指向的对象(即 )大小的信息,该函数可以正确计算表达式str+i
,它等于存储在 中的值str
,加上等于 的值i * 10 * sizeof( char )
。也就是说,结果,指针str
将指向i
二维数组的第 - 个元素,其元素大小等于10
。这就是指针运算的要点。为了更清楚,你可以为二维数组的元素类型引入一个别名,如下所示
反过来,函数声明将如下所示
或者如何
这两个声明声明了相同的函数。
因此,指针寻址的对象的大小将等于
sizeof( T )
,根据引入的别名,它等于sizeof( char[10] )