我正在尝试理解指针在C中是如何工作的。我正在尝试一个简单的例子,其中一个数组和一个指向数组的指针是一个函数的参数,它将复制第二个元素中的第一个元素。
我写了这段代码
#include <stdio.h>
#define TAM 32
typedef int TablaArray[32];
void copyArray(TablaArray, TablaArray*, int);
void main(){
int t1[] = {1,2,3,4};
int t2[4];
copyArray(t1, t2,4);
for(int i = 0; i <= 3; i ++){
printf("%d - %d\n", t1[i], t2[i]);
}
}
void copyArray(TablaArray t1, TablaArray *t2, int tam){
for(int i = 0; i<tam-1; i++){
printf("%d\n", t1[i]);
*t2[i] = t1[i];
}
}
我希望用printf表达式得到类似的东西:
1 - 1
2 - 2
3 - 3
4 - 4
但我肯定不知道方式......我一直在寻找stackoverflow,因为我确信这个微不足道的问题已经得到解答......但我没有找到它......
答案 0 :(得分:1)
您需要确保传递两个指向两个数组的int指针。在您的代码中,只有一个参数是指针。下面的代码应该更清楚:
#include <stdio.h>
void copyArray(int * arr1, int * arr2, int size);
int main(void)
{
int t1[] = {1,2,3,4};
int t2[4];
copyArray(t1, t2,4);
for(int i = 0; i <= 3; i ++)
{
printf("%d - %d\n", t1[i], t2[i]);
}
return 0;
}
void copyArray(int * arr1, int * arr2, int size)
{
for(int i = 0; i < size; i++)
{
printf("%d\n", arr1[i]);
arr2[i] = arr1[i];
}
return;
}
编辑:在你写的内容中,一个TablaArray *是一个指向32个int数组的指针,而你需要一个int *
typedef int TablaArray[32];
是不好的做法
答案 1 :(得分:1)
问题与数组连接到指针衰减,然后是指针算术:
指针衰减意味着如果将类型为int x[32]
的数组对象作为参数传递给函数,那么它就会衰减&#34;指向int *
之类的指针,指向整数数组的第一个元素。因此请注意,如果您传递int x[32]
- 对象,它实际上是通过引用传递的(数组未被复制),您可以更改函数中数组的内容。
现在指针算术:
增加指针(或通过数组下标访问数组)隐式地执行指针算术,并且添加到初始值的字节数取决于指针所指向的对象的类型:
typedef int Array10[10];
Array10 arr = { 1,2,3,4,5,6,7,8,9,0 };
int *x = arr; // arrayOfInts decays to a pointer; x points to the &arr[0]
x++; // in terms of bytes, x is incremented by sizeof(int) bytes
int i = x[3]; // gets the int-value on the address of x + 3*sizeof(int)
Array10 *arr10ptr = arr;
arr10ptr++; // in terms of bytes, x is incremented by sizeof(Array10) bytes, which is 10*sizeof(int)
arr10ptr[3]; // 3*sizeof(Array10), i.e. 3*10*sizeof(int)
现在应该清楚为什么声明为int [32]数组的指针的函数参数与声明为int [32]的函数参数的行为不同。
所以你可以按照以下方式纠正你的程序,现在知道TablaArray t2
将是对底层数组的引用:
void copyArray(TablaArray t1, TablaArray t2, int tam){
for(int i = 0; i<tam; i++){
printf("%d\n", t1[i]);
t2[i] = t1[i];
}
}
希望它有所帮助。
答案 2 :(得分:1)
编译并启用警告。如果您使用gcc -Wall -Werror
,则会出现以下错误:
luis.c:10:6: error: return type of ‘main’ is not ‘int’ [-Werror=main]
void main(){
^~~~
luis.c: In function ‘main’:
luis.c:15:19: error: passing argument 2 of ‘copyArray’ from incompatible pointer type [-Werror=incompatible-pointer-types]
copyArray(t1, t2,4);
^~
luis.c:8:6: note: expected ‘int (*)[32]’ but argument is of type ‘int *’
void copyArray(TablaArray, TablaArray*, int);
^~~~~~~~~
cc1: all warnings being treated as errors
第一个很简单,它应该是int main
。
第二个有点难以确切看到,因为您使用了typedef
。所以你的原型现在是
void copyArray(int *, int (*)[32], int);
第二个值是指向数组的指针,它本身就是一个不经常使用的构造。
相反,你只需要两个指向int
的指针,而数组的大小也许应该使用size_t
代替:
void copyArray(int *, int *, size_t);
void copyArray(int *t1, int *t2, size_t n){
for (int i = 0; i < tam; i++) {
t2[i] = t1[i];
}
}
最后,如果你使用C99,C11编译器,使用可变长度数组数组告诉其中一个参数告诉数组的大小可能会很好;为此我们需要重新排序参数:
void copyArray(size_t, int[*], int[*]);
void copyArray(size_t n, int t1[n], int t2[n]) {
...
}
答案 3 :(得分:0)
void copyArray(TablaArray, TablaArray, int); // prototype
void copyArray(TablaArray t1, TablaArray t2, int tam){
for(int i = 0; i<tam; i++){
printf("%d\n", t1[i]);
t2[i] = t1[i];
}
}
这将有助于
//快得多
#include <string.h>
void copyArray(TablaArray t1, TablaArray t2, int tam){
memcpy(t2, t1, sizeof(t1[0]) * tam);
}
答案 4 :(得分:0)
在您的复制功能中,您在T2的地址上将相同的T1值复制到T2。你可以用指针来做,但指针可以帮助你引用地址