Need help - pointers

N

Nezhate

Hi There,
I'm writing a program that takes a decimal number and returns it's
binary equivalent.
the problem is that I don't know how to return (from function) the
binary value as an array of cocatenated characters. For example : I
want to convert number 3 using 4 bits, ie 3 <----> "0011".
After executing, I'm getting this warning:
warning: return from incompatible pointer type
line:49: warning: function returns address of local variable

Here it is my code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int power (int base, int m);
char* dec2bin(int input, int m);

int main ()
{
int input = 0;
int m = 0;

printf("Number to convert\n");
scanf("%d", &input);
printf ("Number of bits\n");
scanf ("%d",&m);
printf("input %d is converted to %s\n",input,dec2bin(input, m));
exit (0);
}

char* dec2bin(int input, int m)
{
static int i = 0;
char* array[m+1];
int limit = 0;
limit = power(2, m);
const int MASK = limit/2; // the binary equivalent is: 1 + m 0 bits

array[m] = '\0';
for (i= 0; i < m ;i++)
{
if (input & MASK){
strcpy(array,"1");}
else{
strcpy(array,"0");}
input = input << 1;
}
return (array);
}

int power (int base, int m)
{
static int i;
int p=1;
for (i = 1; i <= m; ++i)
{
p =p * base;
}
return p;
}
 
I

Iman S. H. Suyoto

Richard said:
Nezhate said:
Hi There,
I'm writing a program that takes a decimal number

No such thing. Numbers are numbers. Decimal is a positional notation
system. Numbers can be represented in lots of different ways.
and returns it's binary equivalent.

Here's one way:

#include <limits.h>
#include <stddef.h>

char *dec2bin(int n)
{
static char bin[sizeof n * CHAR_BIT + 1];

CMIIW. If the + 1 is for the '\0' terminator, don't we need that
terminator there?
size_t b = sizeof n * CHAR_BIT;
size_t i = 0;

while(b-- > 0)
{
bin[i++] = '0' + !!(n & (1 << b));
}

return bin;
}
 
S

s0suk3

Hi There,
I'm writing a program that takes a decimal number and returns it's
binary equivalent.
the problem is that I don't know how to return (from function) the
binary value as an array of cocatenated characters. For example : I
want to convert number 3 using 4 bits, ie 3 <----> "0011".
After executing, I'm getting this warning:
warning: return from incompatible pointer type
line:49: warning: function returns address of local variable

Here it is my code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int power (int base, int m);
char* dec2bin(int input, int m);

int main ()
{
  int input = 0;
  int m = 0;

  printf("Number to convert\n");
  scanf("%d", &input);
  printf ("Number of bits\n");
  scanf ("%d",&m);
  printf("input %d is converted to %s\n",input,dec2bin(input, m));
  exit (0);

}

char* dec2bin(int input, int m)
{
  static int i = 0;
  char* array[m+1];
  int limit = 0;
  limit = power(2, m);
  const int MASK = limit/2; // the binary equivalent is: 1 + m 0 bits

  array[m] = '\0';
  for (i= 0; i < m ;i++)
    {
      if (input & MASK){
        strcpy(array,"1");}
      else{
        strcpy(array,"0");}
      input = input << 1;
    }
  return (array);

}

int power (int base, int m)
{
  static int i;
  int p=1;
  for (i = 1; i <= m; ++i)
    {
      p =p * base;
    }
  return p;

}


This are the alternatives for returning a string from a function:

- Declare the array to be static, as Pete and Richard Heathfield
did
- Use a dynamic memory allocation function to allocate the array,
but remember to free() the string when you no longer need it
- Declare the function to take a pointer to an array as an
argument, and perhaps an integer representing the maximum number of
characters the buffer can hold
- Make the function operate on a global variable (yuck, don't do
this)

I'd go with the second, since it doesn't retain unneeded memory.

Sebastian
 
M

Martien Verbruggen

Nezhate said:


No such thing. Numbers are numbers. Decimal is a positional notation
system. Numbers can be represented in lots of different ways.


Here's one way:

#include <limits.h>
#include <stddef.h>

char *dec2bin(int n)

Following to your own explanation, above, shouldn't this be called
int2bin(), or maybe num2bin()?

Something called dec2bin probably should have a prototype like:

char *dec2bin(char *dec);

Martien
 
B

Ben Bacarisse

Richard Heathfield said:
Nezhate said:
I'm writing a program that takes a decimal number
and returns it's binary equivalent.

Here's one way:

#include <limits.h>
#include <stddef.h>

char *dec2bin(int n)
{
static char bin[sizeof n * CHAR_BIT + 1];
size_t b = sizeof n * CHAR_BIT;
size_t i = 0;

while(b-- > 0)
{
bin[i++] = '0' + !!(n & (1 << b));

Warning: this is UB in C99 (a signed shift into the sign bit
position[1]). I presume it is OK in C90, but the wording seems vague
to me ("The result of E1 << E2 is E1 left-shifted E2 bit positions" is
all it says about shifts of signed types).
}

return bin;
}

[1] I am paraphrasing, of course (the result is defined only if 1
times 2 to the power b is representable as an int).
 
B

Barry Schwarz

Hi There,
I'm writing a program that takes a decimal number and returns it's
binary equivalent.
the problem is that I don't know how to return (from function) the
binary value as an array of cocatenated characters. For example : I
want to convert number 3 using 4 bits, ie 3 <----> "0011".
After executing, I'm getting this warning:
warning: return from incompatible pointer type
line:49: warning: function returns address of local variable

Here it is my code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int power (int base, int m);
char* dec2bin(int input, int m);

int main ()
{
int input = 0;
int m = 0;

printf("Number to convert\n");
scanf("%d", &input);
printf ("Number of bits\n");
scanf ("%d",&m);
printf("input %d is converted to %s\n",input,dec2bin(input, m));
exit (0);
}

char* dec2bin(int input, int m)
{
static int i = 0;
char* array[m+1];

This defines an array of pointers, not an array of char which you
need.

You have a C99 compiler which allows you to use variable length
arrays?
int limit = 0;
limit = power(2, m);
const int MASK = limit/2; // the binary equivalent is: 1 + m 0 bits

Not after you divide by 2. The binary equivalent has only m-1 zero
bits after the one.
array[m] = '\0';

This sets array[m] to NULL.
for (i= 0; i < m ;i++)
{
if (input & MASK){
strcpy(array,"1");}


This invokes undefined behavior. array does not point to memory
you own. It was never assigned a value so it is indeterminate.
else{
strcpy(array,"0");}
input = input << 1;


Using this approach with a large input and 32 bit int will invoke
undefined behavior when a 1 bit is shifted into the sign bit.
}
return (array);

return is a statement, not a function. The parentheses are
unnecessary.

The expression array has type array of pointer to char. By rule, it
is converted to the address of the first element of the array with
type pointer to array element (essentially &array[0]). In this case,
element type is char* so the expression is converted to type char**.
char** is incompatible with the specified return type (char*) of the
function. And since array is an automatic variable in the function,
it ceases to exist once the function exits so any attempt by the
calling program to evaluate this address invokes undefined behavior.
}

int power (int base, int m)
{
static int i;

What do you think the static buys you?
 
I

Iman S. H. Suyoto

Richard said:
Iman S. H. Suyoto said:
Richard said:
Here's one way:

#include <limits.h>
#include <stddef.h>

char *dec2bin(int n)
{
static char bin[sizeof n * CHAR_BIT + 1];
CMIIW. If the + 1 is for the '\0' terminator, don't we need that
terminator there?

Yes, and it's there. From 3.5.7 (Initialization):

"If an object that has static storage duration is not initialized
explicitly, it is initialized implicitly as if every member that has
arithmetic type were assigned 0 and every member that has pointer type
were assigned a null pointer constant. If an object that has
automatic storage duration is not initialized explicitly, its value is
indeterminate."

Right. Sorry, I forgot about that.

Thanks, Richard.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top