无法将整数数组作为参数传递给局部参数为字符指针的函数
Unable to pass integer array as argument to function whose local argument is character pointer
我有一个 main
函数声明了一个整数数组。我想将此数组传递给参数类型为 char *
的函数。我无法更改被调用函数的签名。
我的目标是将 main
的整数数组 data1
的内容复制到 disp
的整数数组 data2
中,但是当我尝试以下代码时,我得到了不正确的值。
data2[0]= 10,data2[1]= 0,data2[2]= 0,data2[3]= 0,data2[4]= 20.
如何更正它以产生 data2[0]= 10,data2[1]= 20,data2[2]= 30,data2[3]= 40,data2[4]= 50 ?
注意: data2
与 data1
的大小不一定相同。它可以是相同的大小或更大。我希望 data2
的前五个元素最终与 data1
的相应元素相同。
#include<stdio.h>
void disp(char *buffer)
{
int itr, data2[5];
for(itr=0;itr<5;itr++)
{
data2[itr]=(int*)buffer[itr];
printf("data2[%d]= %d\n",itr,data2[itr]);
}
}
int main(void)
{
int data1[5]={10,20,30,40,50};
disp((char*)data1);
return 0;
}
例如在函数中使用这个语句
data2[itr] = *(int*)( buffer + itr * sizeof( int ) );
否则,由于 buffer
的类型为 char *
,因此通常表达式 buffer[itr]
不会指向正确对齐的 int
类型的对象。
或者如 @n. 'pronouns' m
在评论中指出的那样,您可以使用此语句
data2[itr] = ((int*)buffer )[itr];
其实是一样的
那就是你需要正确应用指针算法。
如您所知,您正在向函数发送 int 数组,您可以安全地将其转换为 int *
void disp(char *buffer)
{
int *intBuffer = (int *) buffer;
int itr, data2[5];
for ( itr=0; itr < 5; itr++)
{
data2[itr] = intBuffer[itr];
printf("data2[%d]= %d\n", itr, data2[itr]);
}
}
函数调用似乎不是问题所在。您可以将 data1
强制转换为 char *
,因为这是匹配函数参数类型所必需的。这实际上是一种特殊情况,因为它甚至可以通过结果 char *
.
访问 pointed-to 数据。
问题出在 disp()
中读回数据。本声明:
data2[itr]=(int*)buffer[itr];
已损坏,因为索引运算符 []
的优先级高于强制转换运算符。结果,您正在读取 buffer
指向的数据的 itr
th 字节,将其转换为类型 int *
,将结果转换为隐含到 int
(如果编译器尚未发出警告,请调高编译器的警告级别)并将最终结果存储在 data2
中。可能通过类型 int *
作为中间形式实际上是 no-op.
您可以进行的最简单的更改是插入括号以覆盖默认的运算符优先级:
data2[itr] = ((int*)buffer)[itr];
首先将 buffer
转换回 int *
,然后访问 itr
th int
指向哪个,就是你想要的。
然而,就我个人而言,如果我依赖于参数实际上是一个 int *
但无法正式更新参数类型(但无论如何可以修改函数实现)那么我会创建一个 correctly-typed 复制作为我做的第一件事:
void disp(char *buffer) {
int *int_buffer = (int *) buffer;
那我以后就可以了
// ...
data2[itr] = int_buffer[itr];
// ...
并且通常在处理业务时就好像我已经能够适当地设置参数类型一样。
或者,对于此特定用途,您可以选择简单地执行批量复制:
memcpy(data2, buffer, 5 * sizeof(*data2));
完成,除了打印结果。
在您的代码中 data1
是 int[5]
,五个 int
的数组。您可以将指向它的指针声明为 int (*)[5]
.
查看此代码,从您的 disp()
代码更改而来
void _disp(char* buffer)
{
int(*original)[5] = (int(*)[5])(buffer);
int data2[50];
for (int itr = 0; itr < 5; itr += 1)
{
data2[itr] = (*original)[itr];
printf("data2[%d]= %d\n", itr, data2[itr]);
};
};
显示
Using (*)[5]
data2[0]= 10
data2[1]= 20
data2[2]= 30
data2[3]= 40
data2[4]= 50
对于此代码
#include <stdio.h>
void _disp(char*);
int main(void)
{
int data1[5] = { 10,20,30,40,50 };
printf("\nUsing (*)[5]\n\n");
_disp((char*)data1);
return 0;
}
void _disp(char* buffer)
{
int(*original)[5] = (int(*)[5])(buffer);
int data2[50];
for (int itr = 0; itr < 5; itr += 1)
{
data2[itr] = (*original)[itr];
printf("data2[%d]= %d\n", itr, data2[itr]);
};
};
[在 MSVC 19.27 下编译]
一种可以说更简洁、更灵活的方式
此代码也有效
void _disp2(char* buffer)
{
int* pInt = (int*)buffer;
int data2[50];
for (int itr = 0; itr < 5; itr += 1)
{
data2[itr] = *(pInt + itr);
printf("data2[%d]= %d\n", itr, data2[itr]);
};
};
这里我们只是将buffer
转换为(int*)
,然后使用算术复制值,因为它会在内存中一个接一个地出现。
简答。使用联合和指针,而不是类型转换。
void disp(char *buffer)
{
int itr, data2[5];
for(itr=0;itr<5;itr++)
{
data2[itr]=(int*)buffer[itr];
printf("data2[%d]= %d\n",itr,data2[itr]);
}
}
/* Becomes */
void disp(char *buffer)
{
union tag1 {
char * cptr;
int * iptr;
} u;
int * itrp = NULL; /* or null or even nil depending
on compiler headers...*/
int itr, data2[5];
u.cptr = buffer; /*in as char* */
itrp = u.iptr; /*out as int* */
for(itr=0;itr<5;itr++)
{
data2[itr]= itrp++;
printf("data2[%d]= %d\n",itr,data2[itr]);
}
}
我有一个 main
函数声明了一个整数数组。我想将此数组传递给参数类型为 char *
的函数。我无法更改被调用函数的签名。
我的目标是将 main
的整数数组 data1
的内容复制到 disp
的整数数组 data2
中,但是当我尝试以下代码时,我得到了不正确的值。
data2[0]= 10,data2[1]= 0,data2[2]= 0,data2[3]= 0,data2[4]= 20.
如何更正它以产生 data2[0]= 10,data2[1]= 20,data2[2]= 30,data2[3]= 40,data2[4]= 50 ?
注意: data2
与 data1
的大小不一定相同。它可以是相同的大小或更大。我希望 data2
的前五个元素最终与 data1
的相应元素相同。
#include<stdio.h>
void disp(char *buffer)
{
int itr, data2[5];
for(itr=0;itr<5;itr++)
{
data2[itr]=(int*)buffer[itr];
printf("data2[%d]= %d\n",itr,data2[itr]);
}
}
int main(void)
{
int data1[5]={10,20,30,40,50};
disp((char*)data1);
return 0;
}
例如在函数中使用这个语句
data2[itr] = *(int*)( buffer + itr * sizeof( int ) );
否则,由于 buffer
的类型为 char *
,因此通常表达式 buffer[itr]
不会指向正确对齐的 int
类型的对象。
或者如 @n. 'pronouns' m
在评论中指出的那样,您可以使用此语句
data2[itr] = ((int*)buffer )[itr];
其实是一样的
那就是你需要正确应用指针算法。
如您所知,您正在向函数发送 int 数组,您可以安全地将其转换为 int *
void disp(char *buffer)
{
int *intBuffer = (int *) buffer;
int itr, data2[5];
for ( itr=0; itr < 5; itr++)
{
data2[itr] = intBuffer[itr];
printf("data2[%d]= %d\n", itr, data2[itr]);
}
}
函数调用似乎不是问题所在。您可以将 data1
强制转换为 char *
,因为这是匹配函数参数类型所必需的。这实际上是一种特殊情况,因为它甚至可以通过结果 char *
.
问题出在 disp()
中读回数据。本声明:
data2[itr]=(int*)buffer[itr];
已损坏,因为索引运算符 []
的优先级高于强制转换运算符。结果,您正在读取 buffer
指向的数据的 itr
th 字节,将其转换为类型 int *
,将结果转换为隐含到 int
(如果编译器尚未发出警告,请调高编译器的警告级别)并将最终结果存储在 data2
中。可能通过类型 int *
作为中间形式实际上是 no-op.
您可以进行的最简单的更改是插入括号以覆盖默认的运算符优先级:
data2[itr] = ((int*)buffer)[itr];
首先将 buffer
转换回 int *
,然后访问 itr
th int
指向哪个,就是你想要的。
然而,就我个人而言,如果我依赖于参数实际上是一个 int *
但无法正式更新参数类型(但无论如何可以修改函数实现)那么我会创建一个 correctly-typed 复制作为我做的第一件事:
void disp(char *buffer) {
int *int_buffer = (int *) buffer;
那我以后就可以了
// ...
data2[itr] = int_buffer[itr];
// ...
并且通常在处理业务时就好像我已经能够适当地设置参数类型一样。
或者,对于此特定用途,您可以选择简单地执行批量复制:
memcpy(data2, buffer, 5 * sizeof(*data2));
完成,除了打印结果。
在您的代码中 data1
是 int[5]
,五个 int
的数组。您可以将指向它的指针声明为 int (*)[5]
.
查看此代码,从您的 disp()
代码更改而来
void _disp(char* buffer)
{
int(*original)[5] = (int(*)[5])(buffer);
int data2[50];
for (int itr = 0; itr < 5; itr += 1)
{
data2[itr] = (*original)[itr];
printf("data2[%d]= %d\n", itr, data2[itr]);
};
};
显示
Using (*)[5]
data2[0]= 10
data2[1]= 20
data2[2]= 30
data2[3]= 40
data2[4]= 50
对于此代码
#include <stdio.h>
void _disp(char*);
int main(void)
{
int data1[5] = { 10,20,30,40,50 };
printf("\nUsing (*)[5]\n\n");
_disp((char*)data1);
return 0;
}
void _disp(char* buffer)
{
int(*original)[5] = (int(*)[5])(buffer);
int data2[50];
for (int itr = 0; itr < 5; itr += 1)
{
data2[itr] = (*original)[itr];
printf("data2[%d]= %d\n", itr, data2[itr]);
};
};
[在 MSVC 19.27 下编译]
一种可以说更简洁、更灵活的方式
此代码也有效
void _disp2(char* buffer)
{
int* pInt = (int*)buffer;
int data2[50];
for (int itr = 0; itr < 5; itr += 1)
{
data2[itr] = *(pInt + itr);
printf("data2[%d]= %d\n", itr, data2[itr]);
};
};
这里我们只是将buffer
转换为(int*)
,然后使用算术复制值,因为它会在内存中一个接一个地出现。
简答。使用联合和指针,而不是类型转换。
void disp(char *buffer)
{
int itr, data2[5];
for(itr=0;itr<5;itr++)
{
data2[itr]=(int*)buffer[itr];
printf("data2[%d]= %d\n",itr,data2[itr]);
}
}
/* Becomes */
void disp(char *buffer)
{
union tag1 {
char * cptr;
int * iptr;
} u;
int * itrp = NULL; /* or null or even nil depending
on compiler headers...*/
int itr, data2[5];
u.cptr = buffer; /*in as char* */
itrp = u.iptr; /*out as int* */
for(itr=0;itr<5;itr++)
{
data2[itr]= itrp++;
printf("data2[%d]= %d\n",itr,data2[itr]);
}
}