在声明指向数组的指针并传递给函数时,指针如何工作

时间:2016-12-11 11:49:49

标签: c arrays pointers

好吧,出于某种原因,我无法解决这个问题,但到目前为止,这是我所知道或认为的。

如果我要声明一个char类型的数组char a[8][8],然后声明一个char类型的指针:

char *p = a;

我知道如果我在一个打印语句中推荐一个,我得到第一行的地址 - 如果我只是打印数组a,我仍然得到相同的地址,因为数组a指向第一行行。现在,如果我打印p,我知道我将得到一个指针变量的地址。

无论我是否这样做:

char *p = &achar *p = achar *p = *a,它们是相同的 - 指向同一地址。

当我决定以尊重的方式打印变量p时,会出现问题。当我打印*p时,我得到a[0][0]的值。问题是,当我尝试打印a的尊重时,我再次得到第一行的地址,而不是值a[0][0]

这是否意味着当我为数组创建一个指针变量时,它会跳过指向数组,并直接指向一行?含义:

[*p] = [**a]而不是[*p] = [*a]因为 [char *p = *a] = [char *p = a]

所以通过创建指针,它会跳过?我可能正在思考这一点,或者找到了我的大脑不想接受的规则或属性。

编辑:我现在似乎从弗拉德的回答中了解到。这很奇怪,因为我正在为我的班级做研究问题,我被告知在不使用[]作为练习的情况下制作这样的函数,这就是我试图避开这条道路的原因。

2 个答案:

答案 0 :(得分:1)

char a[3][8]表示你有

  

一个包含8个字符的数组( 3个成员)。

你需要

char (*ptr)[8]=a; // Pointer to an array(of 3 members) of 8 characters

请注意,作为程序员,您需要注意不要访问 超出合法数组范围,即你可以得到的最大值是(*(ptr+2)),因为计数从零开始。即零到两个使三个!!

可以表示为

(*ptr)[8]  // the pointer ptr points to
   V       // the first element of
arr[0][8]  // arr, ie arr[0]

由于C指针支持像解除引用这样的数组,你可以做

ptr[0][1] which is the same as (*(ptr+0))[1]

类似地

ptr[2][7] which is the same as (*(ptr+2))[7] 
//note [2][7] is the maximum bound  for legal access

最后,

有什么问题
char *ptr=a;

使用char *ptr你有一个指针。是啊!那是正确的。当您考虑*ptra的兼容性时,就会出现问题。 a的类型为char[8]。但仅使用char *ptr=a,您无需考虑[8]中的a部分。当您采用size

时,差异会变得清晰
char a[3][8];
char (*ptr)[8]=a;
char *ptr1=a; // A good compiler will warn you about this line.
printf("ptr : %zd\n",sizeof *ptr);
printf("ptr1 : %zd\n",sizeof *ptr1);

给我

ptr : 8 // accounts for eight characters. Here ptr covers the entire
block of eight charactes, so that if you need to go to the next block
of eight characters you could just do "ptr+1" or "ptr[1]
ptr1 : 1 // accounts for just one character.

答案 1 :(得分:1)

如果你有这样一个数组的声明

char a[8][8];

然后这个声明

char *p = a;

无效。

正如您在表达式中正确指出的那样,具有罕见异常的二维数组指示符将转换为指向其第一行的指针。因此,用作初始值设定项的变量a将转换为rvalue类型的char ( * )[8]。类型char *char ( * )[8]的指针不兼容。它们指向不同类型的对象。第一个指向char类型的对象,而第二个指向char[8]类型的对象。

对于地址,数组是一个内存范围。因此,数组本身或其第一行或第一行中第一个元素的地址彼此相等,因为它们都是数组占用的内存范围的地址。

您可以将二维数组解释为一维数组。例如

char *p = ( char * )a;

当然,在这种情况下,您只能将下标运算符应用于指针一次。数组范围将被视为char[ 8 * 8 ]类型为char[64]的一维数组占用的内存。但是,如果原始数组的每一行都包含一个字符串,则可能会出现问题。