Problem with the return value in function - c

I'm trying to tackle this task:Write a function int* dec2bin(int N, int* n) that calculates and returns a binary representation for a natural ¨
number 0 ≤ N < 65535 and returns the binary representation. It holds that n ≤ 16. The function returns the binary representation of N without leading zeros. Note that also the length of the vector is
"
must be returned". For example, the function for ¨ N = 77 returns the vector 1 0 0 1 1 0 1
back. Furthermore, write a calling main program in which ¨ N is read in and the corresponding binary representation is output.
binary representation is output.
Here is the code i wrote:
#include <stdio.h>
int* dec2bin(int N, int* n);
int main(){
int N;
int n[16];
do{
printf("\n input:");
scanf("%d", &N);
}while(N < 0 || N > 65535 );
dec2bin(N,n);
printf("&d has the binaryvalue%d",N,*n);
}
int* dec2bin(int N, int* n){
for(int i=0;N>0;i++){
n[i] = N % 2;
N /= 2;
}
return n[i];
}
Problem:
The compiler tells me that return n[i] is undeclared. I tried loads of things but that made just more problems, help much appreciated

Given
int* dec2bin(int N, int* n){
for(int i=0;N>0;i++){
n[i] = N % 2;
N /= 2;
}
return n[i];
}
the variable i is out-of-scope in the
return n[i];
statement as it ceases to exist when the for loop ends.
Per 6.8.5.3 The for statement, paragraph 1 of the (draft) C11 standard(bolding mine):
The statement
for ( clause-1 ; expression-2 ; expression-3 ) statement
behaves as follows: The expression expression-2 is the controlling
expression that is evaluated before each execution of the loop body.
The expression expression-3 is evaluated as a void expression after
each execution of the loop body. If clause-1 is a declaration, the
scope of any identifiers it declares is the remainder of the
declaration and the entire loop, including the other two expressions;
it is reached in the order of execution before the first evaluation of
the controlling expression. If clause-1 is an expression, it is
evaluated as a void expression before the first evaluation of the
controlling expression.
You need to declare i before the loop:
int dec2bin(int N, int* n){
int i;
for(i=0;N>0;i++){
n[i] = N % 2;
N /= 2;
}
return n[i];
}
Also, int* dec2bin() means dec2bin() returns a pointer to an int but n[i] (were i in scope) would be an int, not a pointer to an int. I changed the code to return int instead of int *. That might not be appropriate.

Related

Printing Fibonacci series using Recursion

//assume (main function)
int fibonacci(int a,int b){
//int i inifinite loop(why?)
static int i=1;
if(i==terms){
return 0;
}
else{
int c;
c=a+b;
a=b;
b=c;
printf(" %d ",c);
i++;
fibonacci(a,b);
return 0;
}
}
If I declare i variable in fibonacci function (definition function) it prints infinite loop of garbage values instead I used static i variable then the code prints Fibonacci series, please explain me how the statics variable works in this code?
If you declare the variable i as having automatic storage duration
int fibonacci(int a,int b){
//int i inifinite loop(why?)
int i=1;
//...
then in each recursive call of the function the variable i is initialized anew by the value 1 and you have an infinite loop of recursive calls.
When you declare the variable i as having static storage duration
int fibonacci(int a,int b){
//int i inifinite loop(why?)
static int i=1;
//...
then it is initialized only once before the program starts.
In any case your function is incorrect because even if the variable i is declared as having static storage duration it is not reset to its initial value after recursive function calls. And moreover it is a bad approach when a function depends on a global variable as your function depends on the global variable terms.
Moreover the Fibonacci series is a fixed series. The user should not specify the variables a and b. It should specify for the function the index of the number in the series that he is going to obtain. And the function should return this number instead of returning 0.
For example the function could be defined the following way
unsigned long long int fibonacci( unsigned int n )
{
return n < 2 ? n : fibonacci( n - 1 ) + fibonacci( n - 2 );
}
Here is a demonstration program.
#include <stdio.h>
unsigned long long int fibonacci( unsigned int n )
{
return n < 2 ? n : fibonacci( n - 1 ) + fibonacci( n - 2 );
}
int main()
{
for (unsigned int i = 0; i < 10; i++)
{
printf( "%u -> %llu\n", i, fibonacci( i ) );
}
}
The program output is
0 -> 0
1 -> 1
2 -> 1
3 -> 2
4 -> 3
5 -> 5
6 -> 8
7 -> 13
8 -> 21
9 -> 34

Can we initiate an array literal with variables in C?

I have been searching if we can initiate an array literal with variables but couldn't find it. Bit of context, I want to pass an array literal to a function. Below is what I am trying to do:
int fun(int * a, int num){
int sum=0;
for (int i=0; i< num; ++i){
sum = sum + a[i];
}
return sum;
}
int main(){
int a = 3, b =2, c = 1 ;
int x[3] = {a,b,c}; // Is this legal? It compiles fine on all compilers I tested.
int p = fun( (int[3]){a,b,c} , 3); // I want to do something like this. pass a literal to the fucntion
return 0;
}
From the C Standard (6.7.9 Initialization)
4 All the expressions in an initializer for an object that has static
or thread storage duration shall be constant expressions or string
literals.
The string literal defined in this record
int p = fun( (int[3]){a,b,c} , 3);
has automatic storage duration. So you may initialize it with non-constant expressions in particularly using the variables a, b, and c.
Pay attention to that as the function does not change the passed array then the first parameter should have the qualifier const and to avoid overflow it is better to declare the return type as long long int.
Here is a demonstration program.
#include <stdio.h>
long long int fun( const int * a, size_t n )
{
long long int sum = 0;
for ( size_t i = 0; i < n; ++i )
{
sum += a[i];
}
return sum;
}
int main( void )
{
int a = 3, b = 2, c = 1 ;
printf( "%lld\n", fun( ( int[] ){a, b, c} , 3 ) );
}
Your code (sans the extra x array) compiles just fine with -std=c99 so yes, I'd say it's standard C99 code.
#include <stdio.h>
int fun(int a[], int num) {
int sum = 0;
for (int i = 0; i < num; ++i) {
sum = sum + a[i];
}
return sum;
}
int main() {
int a = 3, b = 2, c = 1;
int p = fun((int[3]){a, b, c}, 3);
printf("%d", p);
return 0;
}
This would not be allowed if the initializer is static, since the value needs to be assigned before the program executes. From C99:
All the expressions in an initializer for an object that has static storage duration shall be constant expressions or string literals.
Otherwise, each initializer needs to be an "assignment-expression" or, in other words, a valid expression that can be assigned to an object.
So yes, this is legal in C.
Well, yes. The array is being initialized as it should which can be tested by printing it.
The array is also being sent to the function properly as p returns 6. However, do note that you are making a new array to send to the function.

why pre increment works with pointer but not post increment

I stumbled into this while solving an exercise:
void ft_striteri(char *s, void (*f)(unsigned int, char*))
{
unsigned int i;
if (!s || !f)
return ;
i = 0;
while (s[i++])
f(i, s + i);
}
Why doesn't the post increment in the while work while if i do this:
void ft_striteri(char *s, void (*f)(unsigned int, char*))
{
unsigned int i;
if (!s || !f)
return ;
i = -1;
while (s[++i])
f(i, s + i);
}
It works?
I'm new and still very confused to the whole pointer concept is there any nuance here that I don't know about?
The problem is the match between the comparison and the function call.
Consider the first iteration. In the first snippet it would be:
if(!s[0]) break;
f(1, s + 1);
In the second snippet it would be:
if(!s[0]) break;
f(0, s + 0);
The increment operators in C specify that, in addition to a value being computed by the expression, a side-effect occurs.
You might think that this is somehow special or peculiar to these operators, but in fact it isn't. The assignment operators are also this way.
For instance, ++(EXPR) is equivalent to (EXPR) = (EXPR) + 1, except that EXPR is only evaluated once.
Both of these expressions calculate the result (EXPR) + 1, and also have the side effect of storing that value back into (EXPR).
The side effect happens any time during the evaluation of the full expression which contains this subexpression.
Given:
while (s[i++])
f(i, s + i);
We have two full expressions here: the controlling expression of the while loop, s[i++], is a full expression, and so is the f(i, s + i) function call.
The side effects required by each full expression are settled before the next full expression is evaluated. The previous full expression sees the prior value, and the subsequent full expression sees the new value.
In other words, i++ here means:
Calculate the value of i and also put i + 1 into i.
Make sure that this i update is done sometime during the evaluation of the full expression s[i++].
Therefore, the expression f(i, s + i) is going to observe the new value of i, not the previous value of i that was used to calculate s[i]. The function call will not be given the character that was tested to be non-zero, but the next character after it.
The important fact here is that side-effects are sequenced at the level of individual full expressions, not statements. Here, i++ does not mean "increment i after each iteration of the entire while loop, while i keeps referring to the old value". If it worked that way, the code would work; but it doesn't.
Thus your revised statement fixed the consistency:
while (s[++i])
f(i, s + i);
because here ++i means:
Calculate the value of i + 1 and also put that value into i.
Same (2) as above.
Here, the controlling expression of while tests s[i] where i is the new, incremented value of i; and the function call f(i, s + i) refers to the same i. The controlling expression and function call are consistent: they work with the same character of the string.
You had to compensate for the preincrement by initializing i to -1.
If you want to increment a variable after each iteration of the loop, and to do that near the top of the loop, then the for construct is designed for exactly that:
// misconception: // similar idea, correct:
i = 0;
while (s[i++]) for (i = 0; s[i]; i++)
f(i, s + i); f(i, s + i);
The for loop lets us have a kind of "postincrement" at the level of an entire statement: it has a place in the head syntax where we can specify the increment expressions that will evaluate after the entire body.
By the way, since i is unsigned int (which can also be specified as unsigned, without int), that type does not actually have a -1 value in its range. When we do this:
unsigned int x = -1; // initialize or assign a -1 value to unsigned
the negative value gets reduced to the smallest positive residue modulo UINT_MAX + 1, and the resulting value is what is actually assigned.
The value -1 goes to UINT_MAX. So you are really doing this:
i = UINT_MAX; // same meaning as i = -1.
this works because if i is unsigned and contains the maximum value UINT_MAX, when we then increment i, it goes to zero. This modulo or "wrapping" arithmetic is part of the definition of the unsigned type; it is specified in the language standard. In the other direction, decrementing a zero-valued unsigned likewise produces UINT_MAX.
Also, as a matter of style, when referencing arrays, do not mix the ptr + index and ptr[index] notations. This is better:
// while the character isn't null, pass a pointer to that
// same character to f:
while (s[++i])
f(i, &s[i]); // address of the character
This &s[i] means &*(s + i) where the &* ("address of dereferenced pointer") operator combination "algebraically cancels out" leaving s + i; it is no less efficient.
This recommendation is particularly relevant if the function f is working with that one character s[i] and not the entire s + i substring of s. The &array[index] notation tends to be used (as a rule of thumb) when the emphasis is on a particular array element.
As a reader of C, you cannot trust that, of course: &array[index] in someone else's program could be used to calculate a value which a function then uses to access other elements of the array, not only that one. As a writer of C, though, you can make your code "look like what it is doing", so there are fewer pitfalls for someone else.
If you do simple debugging you will see what the problem is.
void ft_striteri(char *s, void (*f)(unsigned int, char*))
{
unsigned int i;
i = 0;
while (s[i++])
{
printf("i = %d\n", i);
if(f) f(i, s + i);
}
}
void ft_striteri1(char *s, void (*f)(unsigned int, char*))
{
unsigned int i;
i = -1;
while (s[++i])
{
printf("i = %d\n", i);
if(f) f(i, s + i);
}
}
int main()
{
ft_striteri("Hello", NULL);
printf("\n");
ft_striteri1("Hello", NULL);
}
https://godbolt.org/z/cqb1aMGje
Result:
i = 1
i = 2
i = 3
i = 4
i = 5
i = 0
i = 1
i = 2
i = 3
i = 4
Function with postincrement iterates from index 1 to 5 instead of 0 to 4.
But your both functions do not use the correct type for the indexes. It should be size_t instead of int.
I would personally write another way, having "positive" test checking if parameters are OK and have only one return point:
void ft_striteri(char *s, void (*f)(unsigned int, char*))
{
size_t i = 0;
if(s && f)
{
while (s[i])
{
f(i, s + i);
i++; // or ++i; - it makes no difference
}
}
}
I don't know about nuance, but here is an equivalent to your first:
void first(char *s, void (*f)(unsigned int, char*))
{
unsigned int i;
if (!s || !f)
return ;
i = 0;
while (s[i]) {
f(i, s + i + 1);
s = s + 1;
}
}
and second:
void second(char *s, void (*f)(unsigned int, char*))
{
unsigned int i;
if (!s || !f)
return ;
i = -1;
while (s[i+1]) {
f(i, s + i + 1);
i = i + 1;
}
}
Really, neither look right to me; I would think you would want:
void ft_striteri(char *s, void (*f)(unsigned int, char*))
{
unsigned int i;
if (!s || !f)
return ;
i = 0
while (s[i]) {
f(i, s + i);
i++
}
}
which, in idiomatic style might be:
void ft_striteri(char *s, void (*f)(unsigned int, char*))
{
int c;
if (!s || !f)
return ;
for (; *s; s++)
f(i, s);
}

Getting error - local variable referenced before being initialized

I have written a simple function which reads in a pointer to an array. It looks at the elements of the array and compares adjacent values for equality. If they are equal it adds their value to "sum"
I am getting a runtime error telling me "local "sum" was referenced before being initialized." I don't understand this because sum is definitely initialized in my function. See code snipet.
int arrRead (char *Pinput){
int sum, a, b = 0;
while (*Pinput){
a = *Pinput;
++Pinput;
b = *Pinput;
if(a == b)
sum += a;
}
return sum;
}
int sum, a, b = 0;
here only b is initialized with 0.
sum and a are uninitialized.
You need to write:
int sum = 0, a = 0, b = 0;
Or, each variable on its own line:
int sum = 0;
int a = 0;
int b = 0;
Even if in your function technically only sum needs to be initialized for the algorithm to work, it is a very good practice to initialize all the variables upon declaration.
Another good suggestion by #melpomene is to narrow the scope of the variables. For instance a and b are used only in the while loop:
int sum = 0;
while (*Pinput){
int a = *Pinput;
++Pinput;
int b = *Pinput;
if(a == b)
sum += a;
}
return sum;
You’re not initializing sum with
int sum, a, b = 0;
Only b is being initialized. You need to add an initializer for sum as well.
int sum=0, a=0, b = 0;
The operator += adds the right side value to the left side value, and then stores the sum back into the left side value.
If sum is uninitialized, the operation sum += X invokes undefined behavior; the result depends on the previous value of sum.

Run Time Check Failure Stack around the variable was corrupted

#include <stdio.h>
main()
{
int num[9], i = 0, count = 0;
while (i<10)
{
scanf("%d", &num[i]);
if (num[i] % 2 == 0)
{
count++;
}
i++;
}
printf("we have %d double numbers\n", count);
}
Run-Time Check Failure #2 - Stack around the variable was corrupted
What should I do?
Your while loop hits all values of i from 0 to 9 inclusive, but attempting to access num[9] takes you out of bounds. You'll need to reduce the while loop range:
while (i<9) {
...
}
In addition, you really should give your main() function a return type, since modern compilers don't tolerate it being missing:
int main()
{
...
return 0;
}
The valid range of indices that can be used to access an array with N elements is [0, N - 1] or that is the same [0, N ).
Thus the condition in the while statement
while (i<10)
has to be rewritten like
while (i < 9)
The reason of the error is using "magic numbers" throughout the program.
Try to use named constants instead of magic numbers, In this case it will be easy to understand what magic number is used in what part of the code.
The program can look like
#include <stdio.h>
#define N 9
int main( void )
{
int num[N];
unsigned int count = 0;
unsigned int i = 0;
while ( i < N )
{
scanf( "%d", &num[i] );
if ( num[i] % 2 == 0 ) ++count;
i++;
}
printf( "we have %u double numbers\n", count);
}
Instead of the while loop it would be better to use a for-loop because the variable i is not used outside the loop.
For example
#include <stdio.h>
#define N 9
int main( void )
{
int num[N];
unsigned int count = 0;
for ( unsigned int i = 0; i < N; i++ )
{
scanf( "%d", &num[i] );
if ( num[i] % 2 == 0 ) ++count;
}
printf( "we have %u double numbers\n", count);
}
A more correct approach of declaring indices of arrays is using the type size_t for them.
In fact the array is not used in the program. You could count even entered values without using an array.
Take into account that according to the C Standard the function main without parameters shall be declared like
int main( void )

Resources