-1

给定一个数组 p[5],编写一个函数将其循环左移两个位置。因此,如果 p[0] = 15, p[1]= 30, p[2] = 28, p[3]= 19 和 p[4] = 61,那么在移位后 p[0] = 28, p[ 1] = 19, p[2] = 61, p[3] = 15 和 p[4] = 30。为 (4 x 5 ) 矩阵调用此函数并将其行左移 2。

下面是我到目前为止的代码,但它不起作用。问题在于,由于辅助函数需要一个参数int *,它不会在主函数中使用数组,因此它做的不对。虽然它编译得很好。

#include<stdio.h>

void moveLeft2(int p[5])
{
    int temp1 = p[0];
    int temp2 = p[1];

    for(int i = 0; i <  5 - 2; i++)
    {
        p[i] = p[i + 2];
    }

    p[3] = temp1;
    p[4] = temp2;
}

int main()
{
    int p[4][5] = {
        {15,30,28,19,61},
        {1,2,3,4,5},
        {6,7,8,9,20},
        {11,12,13,14,15}};
    int i;

    moveLeft2(p);
    return 0;
}

有人可以帮忙吗?

4

2 回答 2

1
void moveLeft2(int p[5])

那个声明实际上是一个谎言。它的意思是

void moveLeft2(int *p)

即传递给的参数moveLeft2应该是一个指向int. 该实现假定指针指向一个足够大的内存块以容纳五个ints,这不是由类型强制执行的,因此是不安全的,但这里重要的一点是函数参数必须具有 type int*

如果你有

int row[5] = {1,2,3,4,5};
moveLeft2(row);

即使在最高警告级别,编译器也不会发出警告。这是因为数组在传递给函数时会转换为指向其第一个元素的指针(以及在大多数其他上下文中;数组不会转换为指向其第一个元素的指针作为sizeof,_Alignof&[address] 运算符的参数)。因此,传递的参数正好具有所需的类型。

宣言

int p[4][5] = {...};

声明p为 4 个数组,int每个数组 5 秒。p[0]是第一个int[5],所以

moveLeft2(p[0]);

是一个类型正确的函数调用(数组p[0]被转换为指向其第一个元素的指针,即&p[0][0])。该数组p[0]是一个由五个组成的数组ints的数组,所以满足实现中的假设,moveLeft2调用不仅类型正确,而且语义正确。

这同样适用于数组(数组)的其他行p,因此

for(i = 0; i < 4; ++i) {
    moveLeft2(p[i]);
}

一个接一个地移动所有四行。

于 2012-11-28T01:36:06.603 回答
0

替代品:

  • void moveLeft2(int p[5])void moveLeft2(int *p)
  • moveLeft2(p);moveLeft2(p[i]);
  • for (i = 0; i < 4; i ++)之前添加moveLeft2(p[i]);

代码:

#include<stdio.h>

void moveLeft2(int *p)
{
    int temp1 = p[0];
    int temp2 = p[1];
    int i;



    for(i = 0; i <  5 - 2; i++)
    {
        p[i] = p[i + 2];
    }

    p[3] = temp1;
    p[4] = temp2;
}

int main()
{
    int p[4][5] = {
        {15,30,28,19,61},
        {1,2,3,4,5},
        {6,7,8,9,20},
        {11,12,13,14,15}};
    int i;

    for (i = 0; i < 4; i ++)
        moveLeft2(p[i]);
    return 0;
}
于 2012-11-29T07:01:17.747 回答