指针调用和值调用 C

标签 c pass-by-reference pass-by-value pass-by-pointer

如何编写这个C程序指针传递和值传递?我创建了这个程序,它生成一个从 -10010010x10 数组,并且主对角线是从下到上读取的,但我不这样做知道如何创建另外两个通过指针和值传递的程序 我必须通过这两种方法再编写两个具有相同输入和输出的程序。我是 C 初学者,我不知道如何做到这一点。

#include <stdio.h>
#include <stdlib.h>

#define N 10
#define M 10

int my_rand(int max, int min)
{
    return (min + rand() / (RAND_MAX / (max - min + 1) + 1));
}

void generate_array(int(*array)[M])
{
    printf("Table:");
    for (int i = 0; i < N; i++)
    {
        printf("\n");
        for (int j = 0; j < M; j++)
        {
            array[i][j] = my_rand(-100, 100);
            printf("%4d ", array[i][j]);
        }
    }
}
void print_diagonal(int(*array)[M])
{
    printf("\n\nThe main diagonal read from bottom to top:\n");
    for (int i = N - 1; i >= 0; i--)
    {
        printf("%4d ", array[i][i]);
    }
}

int *create_array(int(*array)[M])
{
    static int new_array[M] = { 0 };
    for (int i = 0; i < N; i++)
        new_array[i] = array[i][i];
    return new_array;
}

void reverseArray(int arr[], int start, int end)
{
    int temp;
    while (start < end)
    {
        temp = arr[start];
        arr[start] = arr[end];
        arr[end] = temp;
        start++;
        end--;
    }
}

void printArray(int arr[])
{
    int i;
    for (i = N; i < N; i++)
        printf("%4d ", arr[i]);
    printf("\n");
}

int main(void)
{
    int array1[N][M] = { 0 }, *aux_array;
    generate_array(array1);
    print_diagonal(array1);
    aux_array = create_array(array1);
    reverseArray(aux_array, 0, N - 1);
    printArray(aux_array);
}

任何帮助将不胜感激。

最佳答案

C 仅支持按值传递。函数定义中的形式参数始终是内存中与函数调用中的实际参数不同的对象(假设实际参数本身是一个对象,但不一定是)。

我们可以通过传递指针(按值传递)来伪造引用传递语义。这是一个典型的例子:

void swap( int *a, int *b )
{
  int tmp = *a;
  *a = *b;
  *b = tmp;
}

我们接收的不是整数对象,而是指向两个整数对象的指针。我们使用一元 * 运算符来取消引用指针并访问指向的对象。如果我们像这样调用该函数:

int main( void )
{
  int x = 1;
  int y = 2;

  ...
  swap( &x, &y );
  ... 
  return 0;
}

鉴于上述代码,当我们进入 swap 函数时,以下情况成立:

 a == &x        // int *
*a ==  x  == 1  // int

 b == &y        // int *
*b ==  y  == 2  // int

执行swap函数主体后,以下情况成立:

 a == &x        // no change
*a ==  x  == 2

 b == &y        // no change
*b ==  y  == 1

当您将数组表达式作为函数参数传递时,事情就会变得奇怪。 C 有一个规则,当数组表达式不是 sizeof 或一元 & 运算符的操作数时,或者不是用于在声明中初始化字符数组的字符串文字时,表达式从数组类型转换(“衰减”)为指针类型,表达式的值是第一个元素的地址。

IOW,给出代码

int arr[10];

foo( arr );

由于它不是 sizeof 或一元 & 运算符的操作数,因此调用中的表达式 arr to foo 会自动从类型“10-element array of int”转换为“pointer to int”,并且传递给的值foo 是第一个元素的地址; IOW,该调用与写入相同

foo( &arr[0] );

函数定义将写为

void foo( int *a ) // or int a[], which means the same thing
{
  // do something with a[i]
}

IOW,你不能在C中按值传递数组。

所以,看看你的代码:

int my_rand(int max, int min)

maxmin 均按值传递

void generate_array(int(*array)[M])

void print_diagonal(int(*array)[M])

它们接收指向二维数组第一个元素的指针,因此我们伪造了引用传递。

void reverseArray(int arr[], int start, int end)

我们正在接收指向数组第一个元素的指针(T a[]T a[N] 均被解释为 T *a 在函数参数声明中),startend 是按值传递的。

void printArray(int arr[])

我们再次收到一个指向数组第一个元素的指针。

关于指针调用和值调用 C,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49599391/

相关文章:

c - C 中的质数到数组中

c - 将所有变量声明为指针与在 C 中使用地址运算符

java - Java是“按引用传递”还是“按值传递”?

c++ - 重载 = 运算符时返回对象的深层拷贝

c - 段错误 strcpy

c - 如何跳过 GDB 中循环的多次迭代?

使用 fork() 时计数器不会在 a 内增加

perl - 从 Perl 子例程返回整个数组效率低下吗?

php - 关于引用参数或显式返回值的 PHP 方法的最佳实践

c - 按值将数组传递给函数