假设我有以下代码(示例):
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
void Ex(void *ret, int ret_len, int choice){
if(choice==1){
int *ret = ret;
for(int i=0; i<ret_len; i++){
*(ret+i) = i;
}
} else {
int **ret = ret;
for(int i=0; i<ret_len; i++){
for(int j=0; j<ret_len; j++){
*(*(ret+i)+j) = i*j;
}
}
}
}
int main()
{
int m[10];
Ex(m,10,1);
printf("%i",m[3]);
return 0;
}
该函数的目标是获取指向一个或二维数组的预分配内存的指针。
编译和执行时,代码在choice==1
时有效,否则,如果我运行
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
void Ex(void *ret, int ret_len, int choice){
if(choice==1){
int *ret = ret;
for(int i=0; i<ret_len; i++){
*(ret+i) = i;
}
} else {
int **ret = ret;
for(int i=0; i<ret_len; i++){
for(int j=0; j<ret_len; j++){
*(*(ret+i)+j) = i*j;
}
}
}
}
int main()
{
int m[100];
Ex(m,10,2);
printf("%i", m[3][5]);
return 0;
}
没有产生任何输出,代码似乎永远运行(注意选择现在不是1而m是正确的大小)
我的印象是,Ex中的强制转换应该改变数组的形状,并允许main将其索引为它,就像它是2d一样,但是它既没有索引,也没有像1d那样工作,也没有工作。
答案 0 :(得分:0)
因为ret
属于int *
类型,但其他部分是:
for(int i=0; i<ret_len; i++){
for(int j=0; j<ret_len; j++){
*(*(ret+i)+j)=i*j;
}
}
需要ret
类型int **
。这会导致错误。
解决问题的方法是使用void *
。这是在C中使用泛型的一种方法。
查看C中的qsort。
void Ex(void *_ret, int ret_len, int choice){
if(choice==1){
int *ret = (int *)_ret; // <---- type conversion
for(int i=0; i<ret_len; i++){
*(ret+i) = i;
}
} else {
int **ret = (int **)_ret; // <---- type conversion
for(int i=0; i<ret_len; i++){
for(int j=0; j<ret_len; j++){
*(*(ret+i)+j) = i*j;
}
}
}
}
答案 1 :(得分:0)
我提出的现有代码变化最小的最接近的事情是:
#include <stdio.h>
void Ex(int * ret, int ret_len, int choice){
if(choice==1){
for(int i=0; i<ret_len; i++){
*(ret+i)=i;
}
}else{
for(int i=0; i<ret_len; i++){
for(int j=0; j<ret_len; j++){
*(ret + i*ret_len + j) = i*j;
}
}
}
}
int main() {
int anint[10][10];
Ex(anint, 10, 2);
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {printf("%d\n", anint[i][j]);}
}
}
基本上,我手动操纵Ex
函数中的偏移量。我假设两个维度的长度总是相同的。
更“传统的方式”是一个真正的二维数组,其中每个元素都是独立的malloc。因此,第一级数组的元素可以通过力施加到指针并在第二级中被解除引用。但我不愿意多次调用malloc。
我希望这可以解决你的问题。
答案 2 :(得分:0)
看了这个问题的评论和一些答案,这就是我为你的要求所收集的。
您需要一个通用函数,该函数采用choice
维的数组并使用某些值对其进行初始化。
这可以满足您的目的。
void Ex(void *_ret, int ret_len, int choice){
if(choice==1){
int *ret = _ret;
int i;
for(i=0; i<ret_len; i++){
ret[i] = i;
}
} else {
int (*ret)[ret_len] = _ret;
int i, j;
for(i=0; i<ret_len; i++){
for(j=0; j<ret_len; j++){
ret[i][j] = i*j;
}
}
}
}
现在你可以这样称呼它
int main(void) {
int first[10];
Ex(first, 10, 1);
int second[20][20];
Ex(second, 20, 2);
printf("first[4] = %d\n", first[4]);
printf("second[3][4] = %d\n", second[3][4]);
}
您可以看到Demo here