数组作为数组和指针-C传递

时间:2016-08-27 16:52:33

标签: c arrays pointers

为什么此程序会生成pq作为输出?将数组作为指针或数组传递有什么区别。

 #include<stdio.h>

  void fun(char i[]){
   printf("%c,%c", i[1],i[2]);
  }
  void fun2(char *i){
    printf("\n%c,%c", i,i+1);
  }
  int main(){
    char ar[] = {"Aba"};   
    fun(ar);
    fun2(ar);
    return 0;
  }

输出:

  b,a
  p,q

4 个答案:

答案 0 :(得分:3)

您正在第二个函数中打印指针地址的ASCII转换。您必须通过*i*(i+1)取消引用指针。

答案 1 :(得分:0)

  

将数组作为指针或作为指针传递有什么区别   阵列。

这两个函数funfun2都是等效的。所以,你认为fun()中没有真正的数组。 这是因为在C中,当您将数组传递给函数时,它会转换为指向其第一个元素的指针。

所以,fun2()

中的这句话
printf("\n%c,%c", i,i+1);

不打印字符,但地址为ii+1。这也不对,因为它们与您指定的格式不匹配。

当我用gcc编译你的代码时,它警告:

In function ‘fun2’:
warning: format ‘%c’ expects argument of type ‘int’, but argument 2 has type ‘char *’ [-Wformat=]
     printf("\n%c,%c", i,i+1);
            ^
warning: format ‘%c’ expects argument of type ‘int’, but argument 3 has type ‘char *’ [-Wformat=]

如您所见,格式说明符和您传递的参数不匹配。打印ii+1的值 指向,您可以像在fun()中一样打印它:

 int fun2(char *i){
    printf("\n%c,%c", i[1],i[2]);
 }

答案 2 :(得分:0)

要打印该值,您应在两个函数中使用class Protocol<T> { func sayHello(name: String = "World") { print("Hello, \(name)!") } } class Class<T>: Protocol<T> { override func sayHello(name: String = "Stack Overflow") { super.sayHello(name) } } Class<()>().sayHello() *i*(i+1)i[0]i[1]包含您传递的数组的第一个地址单元格。在任何一种情况下,都会传递他们的地址。

答案 3 :(得分:-1)

希望我在这里的长篇答案有所帮助!

我采用了整数,这个概念对于任何数据类型都是一样的:char,float等等。

好的,关于数组和指针的快速简短课程。

Thumb规则1:数组和指针几乎总是可互换的,但也有例外!

采用一维数组,我们可以这样声明: -

int arr[10];

这声明了一个名为arr的变量,它可以容纳10个整数元素。

我可以类似地使用指针表示法来使用指针变量或使用数组名称(arr)本身来表示此数组。

printf ("%d", arr[2]); // Array method : will print out the third element, indexing starts from 0

Thumb规则2:数组名称(无论是1D 2D 3D 4D)总是衰减为指针或地址。

printf ("%lu", arr) //will print out the base address of the array, i.e address of the first element

如何使用指针打印值?简单地说,使用*运算符取消引用它。

printf("%d", *arr) //Pointer notation - will print the first value

如何使用另一个变量引用数组?

 int *ptr = arr; //Pointer notation - just simply write the array name as it decays into an address

printf("%d", *ptr); //Pointer notation - prints the first element

很多人说 int * ptr 是指向数组的指针。

实际上并非如此。它实际上是指向整数而非数组的指针。为什么呢?

因为首先我们存储数组的第一个整数的地址,然后我们可以通过递增指针来遍历它。因此,在实际指针中存储整数的地址(第一个整数)。

现在,来到2D阵列: -

声明: -

int arr[2][3]; // arrays of 2 rows and 3 columns, total 6 elements

同样的规则意味着: -

printf("%d", arr[0][1]); //prints the second element of the first row.

printf("%lu", arr) //prints the base address of the 2D array

来指针符号: -

printf("%d", *(*(arr + 0) + 1); // how this works?

arr包含地址。通过向其添加整数,可以跳转到该行。

arr + 1 // gives the second row, i.e. arr is currently pointing to the first element of second row.

现在,进一步向其添加一个整数,将跳转到该特定行中的指定列。

((arr + 1) // second row  +  2 ) // will you skip to third element of the second row

当您选择将数组名称视为指针时,这是语言提供的隐式指针表示法。

现在出现问题: - 显式指针表示法: -

你想要实现的是,将2D数组的基地址存储在指针中。

如何正确地做到这一点?

int (*ptr)[3]; //reading it goes like this - ptr is a pointer to a 1D array of 3 ints

此处的3指定了2D数组的列数。

所以它正在做的是,试图将该2D阵列的第一个 1D数组的基地址(这意味着第0行基地址)存储到指针中。

其余的保持不变。

int (*ptr)[3] = arr; // storing the 2D array in ptr

现在,您可以将它用作普通指针(指针符号适用于它)

(ptr + 1) //now ptr is pointer to the Second 1D array of that 2D array or you can say to the second row's first element.

另一种可以在函数中捕获数组的方法是: -

我使用它的次数非常少。

int main()
{
    int arr[2][2];
    fun(arr);
}

void fun(int catch[][])
{


}


// This is simple to understand and as well as to relate. Now, again catch can be used as pointer or as an array. It depends on you :)

void fun1(int (*ptr)[2])
{
      //my way
printf("%d", ptr[1][1]);
printf("%d", *(*(ptr + 1) + 1));

//answer will be the same
}

//Ptr now contains that 2D array base address, again can be used as an array or a pointer :)