【问题标题】:Why the pointer from called function doesn't return the value to calling function?为什么被调用函数的指针不将值返回给调用函数?
【发布时间】:2017-03-24 03:09:15
【问题描述】:
#include<stdio.h>
#include<stdlib.h>
unsigned int *bin(int);
int main(void)
{
  unsigned int n=0,*i=NULL;
  printf("Enter no:");
  scanf("%d",&n);
  i=bin(n);
  printf("Binary no: %d\n",*i);
  return 0;
}
unsigned int *bin(int n)
{
  unsigned int i=0,j=0;
  static unsigned int *result=NULL;
  result=(unsigned int*)malloc(1*sizeof(unsigned int));
  printf("Result=%p\n",result);
  j=(unsigned int)result;
  for(i=(1<<31);i>0;i=(i>>1))
  {
    if(n & i)
    {
      *result=1;
      result++;
    }
    else
    {
      *result=0;
      result++;
    }
}
  result=(unsigned int*)j;
  printf("Result=%p\n",result);
  return result;
}
Output : 
Enter no:6
Address of Result=0x2576010
Address of Result=0x2576010
Binary no: 0

本程序的目的是将十进制数转换为二进制数。主要功能是调用bin()函数将十进制数转换为二进制数。

代码逻辑:- 让我们取无符号整数(32 位),它由 0-31 位组成。要打印无符号整数的二进制表示,从第 31 位开始,检查第 31 位是 ON 还是 OFF,如果是 ON,则打印“1”,否则打印“0”。现在检查第 30 位是 ON 还是 OFF,如果是 ON 打印“1”,否则打印“0”,对从 31 到 0 的所有位执行此操作,最终得到数字的二进制表示。

我很困惑应该分配多少空间来存储 32 位整数。以及如何释放分配给结果的内存。请帮我解决这个代码。

【问题讨论】:

  • j=(unsigned int)result;... 为什么?指向整数转换的指针高度依赖于实现。如果需要,请使用uintptr_t
  • 不要使用强制转换来消除编译器错误。相反,问问你做错了什么。
  • @SouravGhosh 最好先问问为什么j 必须是任何类型的整数。
  • result=(unsigned int*)malloc(1*sizeof(unsigned int)); 您在这里分配了 4 个字节(或者可能是 8 个字节,具体取决于您的平台)的内存,这还不够。但是有更多的问题,代码真的很奇怪。
  • 你分配了多少个整数? 打印出那个号码。那是你想做的吗?再说一次,你在最终的 printf 中打印了多少个整数?与您分配的号码相同吗?如果没有,为什么不呢?

标签: c pointers


【解决方案1】:

考虑到 1 和 0 的数据类型是 char,您将需要分配 32 字节(至少)的内存来存储对应于 n 中每个位的 1 或 0。此外,我建议使用 int 作为数据类型并分配 32x4(字节)的内存。您的最终代码可能如下所示:

#include<stdio.h>
#include<stdlib.h>
unsigned int *bin(int);
int main(void)
{
  unsigned int n=0,*result =NULL;
  printf("Enter no:");
  scanf("%d",&n);
  result =bin(n);
  printf ("binary representation is: ");
  int i;
  for ( i=0;i<32;i++)
    printf("%d ",result[i]);
  free(result);
  return 0;
}

unsigned int *bin(int n)
{
  unsigned int i=0;
  static unsigned int *result=NULL;
  result=(unsigned int*)malloc(32*sizeof(unsigned int));
  printf("Result=%p\n",result);
  unsigned int* j=NULL;
  j=result;
  for(i=(1<<31);i>0;i=(i>>1))
  {
    if(n & i)
    {
      *j=1;
      j++;
    }
    else
    {
      *j=0;
      j++;
    }
}

  return result;
}

【讨论】:

  • 你应该把free(result)放在main的末尾。
  • 您对我在函数 bin() 中声明的静态指针 *result 有何看法。即使我没有声明它是静态的,它也可以工作。但是,如果它没有声明为静态,它的类就变成了自动的,它的作用域将在函数 bin() 内,一旦函数 bin() 完成执行,它就会被销毁,对吗?但即使它的自动指针它仍然有效。为什么会这样?
  • 因为这里的结果本身没有内存(32* sizeof(unsigned int) 字节)。它只是指向相同的内存。所以即使它的作用域在 bin() 函数内,之前由 malloc 函数创建的结果指针指向的内存范围仍然是直到程序结束。
  • 好。但是,您建议使用 32 个字符(字节,8 位实体),但您分配了 32 个int,这些字符串函数不容易处理。请参阅下面的建议(包含 33 个字符,既可以作为数组操作,也可以作为常规 C 字符串轻松打印)。
【解决方案2】:

Shubham,我真的认为你走错了方向,因为首先没有十进制或二进制整数之类的东西。让我建议您使用 malloc 和不需要的 static 指针来解决您的问题:

/*
 * return a 32-bit long binary string from 'integer'
 *  this string is dynamically allocated (malloc)
 * return NULL in case of error (so DON'T free it in this case)
 */
char* bin(long integer)
{
 char* pChResult=malloc(33*sizeof(char));
 char* pCh;
 unsigned long i;
 if(pChResult!=NULL) {
   for(pCh=pChResult, i=1<<31; i>0; pCh++, i>>=1) {
    if(i&integer)
     *pCh='1';
    else
     *pCh='0';
    }
   *pCh='\0';
  }
 return(pChResult);
}

你的主菜也会很轻:

int main(void)
{
  unsigned int n;
  char* result;
  printf("Enter no:");
  scanf("%d",&n);
  result = bin(n);
  if(result==NULL)
   {
    fprintf(stderr, "internal error!\n");
    return(-1);
   }
  printf("binary representation is: %s\n", result);
  free(result);
  return(0);
}

【讨论】:

    【解决方案3】:

    32 位整数值强制使用signed longunsigned long

    在函数bin 中,只要您需要存储结果,就一直使用*result 然后return(result);

    主要使用*resultfree(result); 当你完成结果时

    为什么不直接unsigned long bin(long);

    最后,你的函数什么都不做!应该类似于void bin(long, char[33]);(不需要malloc)或char* bin(long);(带有malloc

    【讨论】:

    • 您对我在函数 bin() 中声明的静态指针 *result 有何看法。即使我没有声明它是静态的,它也可以工作。但是,如果它没有声明为静态,它的类就变成了自动的,它的作用域将在函数 bin() 内,一旦函数 bin() 完成执行,它就会被销毁,对吗?但即使它的自动指针它仍然有效。为什么会这样?
    • 不完全。如果result 是一个指向malloc 数据的指针,那么return(result); 将返回malloc 数据的地址。在bin 范围内保留此地址的内存位置会丢失,但您不在乎。类似return(&amp;result); 的错误会是什么。
    猜你喜欢
    • 1970-01-01
    • 2018-06-04
    • 1970-01-01
    • 2013-10-14
    • 2017-03-25
    • 1970-01-01
    • 1970-01-01
    • 2016-10-07
    • 2018-01-12
    相关资源
    最近更新 更多