[英]array passed as array and pointer-C
为什么该程序产生p
和q
作为输出? 将数组作为指针或数组传递有什么区别?
#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
您正在第二个函数中打印指针地址的ASCII转换。 您必须通过*i
和*(i+1)
解引用指针。
将数组作为指针或数组传递有什么区别?
fun
和fun2
这两个函数的签名是等效的。 因此,您实际上并不像您想的那样在fun()
有一个数组。 这是因为在C语言中,当您将数组传递给函数时,它将转换为指向其第一个元素的指针。
所以,这条语句在fun2()
printf("\n%c,%c", i,i+1);
不打印字符,但地址i
和i+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=]
如您所见,格式说明符和传递的参数不匹配。 要打印i
和i+1
指向的值,可以像在fun()
那样打印它:
int fun2(char *i){
printf("\n%c,%c", i[1],i[2]);
}
要打印值,您应该在两个函数中都使用*i
和*(i+1)
或i[0]
和i[1]
。 i
包含您传递的数组的第一个地址单元。 在任何一种情况下,两者都通过其地址。
希望我的长答案对您有所帮助!
我采用整数,该概念对于任何数据类型均相同:char,floats等,等等。
好吧,关于数组和指针的简短课程。
经验法则1:数组和指针几乎总是可以互换的,但是也有例外!
以一维数组为例,我们可以这样声明:-
int arr[10];
这将声明一个名为arr
的变量,该变量可以容纳10个整数元素。
我可以类似地使用指针表示法通过指针变量或通过使用数组名( arr
)本身来表示此数组。
printf ("%d", arr[2]); // Array method : will print out the third element, indexing starts from 0
经验法则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是指向数组的指针。
实际上不是。 实际上,它是指向整数而不是数组的指针。 为什么?
因为首先要存储数组的第一个整数的地址,然后可以通过增加指针来遍历它。 因此,在实际指针中存储的是整数(第一个整数)的地址。
现在,进入二维数组:
宣言:-
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 :)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.