C指针解引用错误
假设我有以下代码(示例): 不会产生任何输出,代码似乎永远运行(注意,选择现在不是1,m是正确的大小)C指针解引用错误,c,arrays,pointers,compiler-errors,C,Arrays,Pointers,Compiler Errors,假设我有以下代码(示例): 不会产生任何输出,代码似乎永远运行(注意,选择现在不是1,m是正确的大小) 我的印象是,Ex中的铸件应该改变阵列的形状,并允许main索引到阵列中,就像它是2d一样,但既不能索引到阵列中,就像它是1d也不能索引到2d工作一样。因为retif类型int*,但其他部分是: for(int i=0; i<ret_len; i++){ for(int j=0; j<ret_len; j++){ *(*(ret+i)+
我的印象是,Ex中的铸件应该改变阵列的形状,并允许main索引到阵列中,就像它是2d一样,但既不能索引到阵列中,就像它是1d也不能索引到2d工作一样。因为
ret
if类型int*
,但其他部分是:
for(int i=0; i<ret_len; i++){
for(int j=0; j<ret_len; j++){
*(*(ret+i)+j)=i*j;
}
}
我提出的对现有代码更改最少的最接近的东西是:
#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]);}
}
}
#包括
void Ex(int*ret、int ret_len、int choice){
如果(选项==1){
对于(int i=0;i,在查看了对问题的评论和一些答案后,这是我为您的要求收集的内容
您需要一个通用函数,它接受一个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;
}
}
}
}
你可以看到*(ret+i)
的类型是int
,所以*(int\u value+j)
不能取消引用。是的,这一行*(*(ret+i)+j)=i*j;
没有意义。ret[i][j]
和*(*(ret i)+j)之间唯一的区别是
是指一个比另一个更短、更容易阅读、更难出错-如果ret
的参数类型是int**ret
(或int*ret[20]上的某个变体)。如果将ret
定义为int*ret
,则任何双解引用都是错误的。请注意,类型int**ret
和int*ret[20]
非常不同,即使您可以使用ret[i][j]
。@BLUEPIXY这很有意义,但是如何用传统的方法来实现呢?根据您使用malloc
的安全性,我认为有必要将一维数组计算为二维数组,这与您的解释相反。我尝试了void指针,但没有找到类型。这个答案肯定是正确的mpiles,这对我来说很有意义。你真的需要声明一个新变量吗?还是像显式强制转换那样为了清晰起见这么做了?如果你不强制转换,为什么编译器会担心?似乎如果我不强制转换并且有void*ret
,那么它很可能是指向指针的指针still@CircArgs否,新变量声明是这不是必须的,只是为了清楚起见。我不必遍历malloc,所以我认为int**ret=(int**)_ret;
不正确。@BLUEPIXY你是说这个循环通过malloc
?我没有透露我是如何分配内存的。我只是不想得到建议在function@CircArgs请告诉我你是如何保护调用方的内存的。你真的能索引到多维数据库吗数组就像你的else语句中的1d一样?我在测试这个时遇到了困难,因为它似乎不起作用。在Mac或Linux上,gcc aa.c
,然后/a.out
你的答案肯定有效。如果你不介意的话,我会接受几个问题。int*ret=\u ret;
有必要吗?int中发生了什么(*ret)[ret\u len]=\u ret;
?感谢您的帮助int*ret=\u ret
是必需的,因为\u ret
属于void*
类型,您不能直接取消引用void*
。其他方法是在使用as((int*)\u ret)[i]时强制转换
,但这很难看,所以我将其转换为一个单独的变量。至于int(*ret)[ret_len]
它被定义为指向大小为ret_len
的int数组的指针,这也是int[ret_len][ret ret len 20]的int也会衰减的内容。这是取消引用最初声明为int[20][20]的变量的正确方法
。您可能已经看到int-ret**
在其他地方也被使用,但这是一个指向int类型指针的指针,需要在循环中使用malloc
(或非标准alloc
)进行初始化。我必须再读几遍才能完全单击它。谢谢。我接受了您的答案
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;
}
}
}
}
#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]);}
}
}
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]);
}