this is the function code:
void statistics(int arr[], int n, int *positive, int *even, int *doubledigit)
{
int i = 0, countP = 0, countE = 0, countD = 0;
for(i = 0; i < n; i++)
{
if(arr[i] > 0)
countP++;
if((arr[i] % 2) == 0)
countE++;
if(abs(arr[i]) >= 10 && abs(arr[i]) < 100)
countD++;
}
*positive = countP;
*even = countE;
*doubledigit = countD;
}
void main()
{
// double mat[size][size];
int *positive = NULL, *even = NULL, *DoubleDigit = NULL;
int arr4[] = {1, 3, 5, -45, 8, 8, 60, 800};
int soa = sizeof(arr4);
statistics(arr4, soa, &positive, &even, &DoubleDigit);
}
the problem is that the result of the even numbers is 28:
why is it 28?? it should count the even numbers...
http://i.stack.imgur.com/dS2us.png
First the return type of main() should be int.
Secondly for some reason you are passing the addresses of int pointers (that are initialised to NULL) to your function. Just pass int* parameters to your function like you should be.
Thirdly, sizeof returns the size of the array in bytes. You want to iterate over the number if elements in the array, not the byte count. Therefore you need to divide the byte count by the number of bytes in each element (sizeof(int)).
Try this instead
int main()
{
int positive =0, even = 0, DoubleDigit = 0;
int arr4[] = { 1, 3, 5, -45, 8, 8, 60, 800 };
int soa = sizeof(arr4)/sizeof(int);
statistics(arr4, soa, &positive, &even, &DoubleDigit);
}
Memory addresses of some value-buckets are stored in these:
int *positive = NULL, *even = NULL, *DoubleDigit = NULL;
You want to declare actual value-buckets where to store the results/values, not the storage for addresses, so change to:
int positive = 0, even = 0, DoubleDigit = 0;
Also, you want the number integers in arr4, so change to:
int soa = sizeof(arr4) / sizeof(int);
In your main() function: positive even DoubleDigit has been a pointer. However you pass their address to function statistics().
statistics(arr4, soa, &positive, &even, &DoubleDigit);
is equal to
statistics(int arr[],int soa,int **positive, int **even, int **DoubleDigit);
but you declare it as
statistics(int arr[], int n, int *positive, int *even, int *doubledigit)
Try the following
void statistics( const int arr[], int n, int *positive, int *even, int *doubledigit )
{
int i;
for ( i = 0; i < n; i++ )
{
if ( arr[i] > 0 ) ++*positive;
if ( arr[i] % 2 == 0 ) ++*even;
if ( abs( arr[i] ) >= 10 && abs( arr[i] ) < 100 ) ++*doubledigit;
}
}
int main( void )
{
int positive = 0, even = 0, DoubleDigit = 0;
int arr4[] = { 1, 3, 5, -45, 8, 8, 60, 800 };
int soa = sizeof( arr4 ) / sizeof( *arr4 );
statistics( arr4, soa, &positive, &even, &DoubleDigit );
}
As for your code then you declared pointers
int *positive = NULL, *even = NULL, *DoubleDigit = NULL;
but they do not point to actual memory.
You call the function parsing addresses of the pointers themselves
statistics(arr4, soa, &positive, &even, &DoubleDigit);
that is for example expression &positive has type int ** while the corresponding parameter of the function
void statistics( const int arr[], int n, int *positive, int *even, int *doubledigit )
is declared as having type int *
Expression sizeof(arr4) yields the size in bytes of array arr4 while you have to pass the numjber of elements in the array.
Function main shall have return type int
int main( void )
{
//...
}
Related
My function writePrime has to write all prime numbers from array using pointer arithmetic. I cannot use any other function except main and writePrime.
#include <stdio.h>
void writePrime(int arr[], int n) {
int *q = arr, *qq = arr, i, prime;
while (q < arr + n) {
while (qq < arr + n) {
i = 1;
if (*qq % i != 0)
continue;
else
prime = 1;
i++;
qq++;
}
if (prime == 1)
printf("%d ", *q);
q++;
}
}
int main() {
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 92, 93, 94, 95, 96};
int n = sizeof(arr) / sizeof(*arr);
writePrime(arr, n);
return 0;
}
This code just prints the same unchanged array. How could I modify this to work?
The variable n should be declared as having the type size_t
size_t n = sizeof(arr) / sizeof(*arr);
because it is the type of an expression with the sizeof operator.
So the function should be declared like
void writePrime( const int arr[], size_t n );
Using two loops with two pointers within the function does not make a sense.
Each variable is divisible by 1. So this code snippet
i = 1;
if (*qq % i != 0)
continue;
else
prime = 1;
also does not make any sense.
And you are using initially uninitialized variable prime that must be reset before processing each element of the array.
The function can be defined the following way
void writePrime( const int arr[], size_t n )
{
for ( const int *p = arr; p != arr + n; ++p )
{
int prime = *p % 2 == 0 ? *p == 2 : *p != 1;
for ( int i = 3; prime && i <= *p / i; i += 2 )
{
if ( *p % i == 0 ) prime = 0;
}
if ( prime ) printf( "%d ", *p );
}
putchar( '\n' );
}
I want to find the number within a range in an array and must be in a recursive way. The function variables couldn't be modified.
Let's say in the range of 2 and 3
The input is : int a[] = {4, 1, 3, 1, 3, 2};
and the output will be = {3,3,2} , 3 found
Not sure how to code the recursive function in this case. The below I have tried not working.
int within(int a[], int N, int lower, int upper, int result[])
{
if(N == 1 && N <= upper && N>= lower)
return a[0];
return within(&a[1], N-1, lower, upper, result);
}
int main()
{
int a[] = {4, 1, 3, 1, 3, 2};
int result[6] = {0};
int i, nResult;
nResult = within(a, 6, 2, 3, result);
printf("%d data passed the bounds\n", nResult);
for (i = 0; i < nResult; i++){
printf("%d ", result[i]);
}
printf("\n");
return 0;
}
I want to find the number within a range in an array
Let's say in the range of 2 and 3
Normally a for loop or similar would be so much easier here
If it has to be recursive....
// need to have another number - r - number in range
// r starts at zero
//
// normally lower case for variable and capitals for things you #define
// N starts at the number of elements of a less one
//
int within(int a[], int N, int lower, int upper, int r, int result[])
{
if(a[0] <= upper && a[0]>= lower) {
result[r]= a[0];
r++;
}
if(N==0) {
return r;
} else {
r = within(&a[1], N-1, lower, upper, r, result);
return r;
}
}
the function will give a return value of the number of values found within the range.
The code above is recursive, but so much more complicated and fragile than a simple loop... such as the fragment below
for (i=0;i<N;i++) {
if(a[i] <= upper && a[i]>= lower) {
result[r]= a[i];
r++;
}
}
If it has to be recursive wihtout r...
// need to have another number - result[0] - number in range
// result[0] starts at zero
//
// normally lower case for variable and capitals for things you #define
// N starts at the number of elements of a less one
//
int within(int a[], int N, int lower, int upper, int result[])
{
if(a[0] <= upper && a[0]>= lower) {
result[0]++;
result[result[0]]= a[0];
}
if(N==0) {
return result[0];
} else {
result[0] = within(&a[1], N-1, lower, upper, result);
return result[0];
}
}
now result conatins
{number in range, first number in range, second number in range....}
Something like this. If you want to implement a recursive function, try to do it in the way that the recursive call happens at the end.
#include <stdio.h>
int find_in_range(int* out, int const *in, int length, int from, int to)
{
if (length == 0)
{
return 0;
}
int addon;
if (*in >= from && *in <= to)
{
*out = *in;
++out;
addon = 1;
}
else
{
addon = 0;
}
return find_in_range(out, in + 1, length - 1, from, to) + addon;
}
#define N 6
int main()
{
int in[N] = {4, 1, 3, 1, 3, 2};
int out[N] = {0};
int num_found = find_in_range(out, in, N, 2, 3);
for (int i = 0; i < num_found; ++i)
{
printf("%d ", out[i]);
}
printf("\n");
return 0;
}
You can modify the following code as per your requirements. This is just a proof of concept code:
#include <stdio.h>
#include <stdlib.h>
static int result[4];
static int ctr1 = 0;
static int ctr2 = 0;
void recFind(int* arr, int* key){
if(ctr2 == 8)
return;
if(*arr >= key[0] && *arr <= key[1])
result[ctr1++] = *arr;
arr++;
ctr2++;
recFind(arr, key);
}
int main(){
int arr[] = {1,3,3,6,4,6,7,8};
int key[] = {1,4};
recFind(arr, key);
printf(" { ");
for(int i = 0; i < 4; i++){
printf("%d ", result[i]);
}
printf("}\n");
}
As it follows from the description of the assignment the function should provide two values: the number of elements that satisfy the condition and an array that contains the elements themselves.
It is evident that the array should be allocated dynamically. And it is logically consistent when the function itself returns the number of elements while the pointer to the generated array is passed by reference as an argument.
The recursive function can look the following way
#include <stdio.h>
#include <stdlib.h>
size_t get_range( const int a[], size_t n, int lower, int upper, int **out )
{
size_t m;
if ( n )
{
m = get_range( a, n - 1, lower, upper, out );
if ( lower <= a[n-1] && a[n-1] <= upper )
{
int *tmp = realloc( *out, ( m + 1 ) * sizeof( int ) );
if ( tmp )
{
tmp[m] = a[n-1];
*out = tmp;
++m;
}
}
}
else
{
*out = NULL;
m = 0;
}
return m;
}
int main(void)
{
int a[] = { 1, 2, 3, 4, 5, 4, 3, 2, 1 };
const size_t N = sizeof( a ) / sizeof( *a );
int lower = 2, high = 3;
int *out;
size_t n = get_range( a, N, lower, high, &out );
for ( size_t i = 0; i < n; i++ )
{
printf( "%d ", out[i] );
}
putchar( '\n' );
free( out );
return 0;
}
The program output is
2 3 3 2
Below codes will work for you in recursive way. If you don't want to print the numbers just comment out printf statement inside function printfRange. Hope you can understand the logic :-
int within(int *a, int rngH, int rngL, int length)
{
int len = length;
static int i = 0;
static int found = 0;
if(len <=0 )
{
return i;
}
if (*a == rngH)
{
printf("%d,",*a);
i++;
found = 1;
within(++a,rngH, rngL,--len);
}
else if(*a == rngL && found > 0)
{
printf("%d,",*a);
i++;
within(++a,rngH, rngL,--len);
}
else
{
within(++a,rngH, rngL,--len);
}
return i;
}
int main() {
int a[] = {4, 1, 3, 1, 3, 2};
int total = within(a,3,2,6);
printf("\n");
printf("Total :%d\n",total);
return 0;
}
I have an array of numbers that has been sorted in before, so there's no need to sort it, I need to insert an given value, named it val, at a valid position in my array.
My program works for a given value that is smaller than the last one, but for the case where the value is bigger than the last one, my program just doesn't want to insert the value.
For example, for the array {1, 2, 3, 4, 6} and the value 5, the array should be {1, 2, 3, 4, 5, 6}, but for the value 7 my array is looking like {1, 2, 7, 4, 6, 0}.
#include <stdio.h>
void insert(int val, int *n, int v[])
{
int index;
index = n - 1;
if (n == 0)
{
v[0] = val; // check if array is empty
n = n + 1; // v[0] becomes the given value
} // increase size of array
if (val > v[index])
{
v[index+1] = val; // given value is bigger than the last value in array
n = n + 1; // increase size
}
else
{
while (index >= 0 && v[index] > val)
{
v[index+1] = v[index]; //shift items to the right
index--;
}
v[index + 1] = val; //after moving elements to the right
n = n + 1; // i set the value to the valid position
}
}
void display(int n, int v[])
{
int i;
for (i = 0;i < n; i++)
printf("%d ", v[i]);
}
int main(void)
{
int v[10] = { 12, 23, 34, 41, 69, 71, 81, 91, 100 };
int n;
n = 9; // size of array
insert(101,n,v); // 101 is given value to insert
display(n,v);
return 0;
}
You have a couple of mistakes:
You are passing int instead of int * so you're not able to update array size
You are not correctly placing value in the array
This is how your code should look like:
#include <stdio.h>
void insert(int val, int *nPtr, int v[]);
void display(int n, int v[]);
int main(void) {
int v[10] = {12, 23, 34, 41, 69, 71, 81, 91, 100};
int n;
n = 9;
insert(101, &n, v);
display(n, v);
return 0;
}
void insert(int val, int *nPtr, int v[]) {
int n = *nPtr;
int i, j;
int k = 0;
for (i = 0; i < n + 1; i++)
if (!k) {
if (v[i] > val || i == n) {
for (j = n - 1; j >= i; j--) {
v[j + 1] = v[j];
}
v[i] = val;
n++;
k = 1;
}
}
*nPtr = n;
}
void display(int n, int v[]) {
int i;
for (i = 0; i < n; i++)
printf("%d ", v[i]);
printf("\n");
}
You can also try to insert number on the beginning, for example 0 and it will still work.
So, I have this so far. I'm trying to find the two largest numbers in an array and return them. I looked up a lot of resources online, and most of them say "call by reference" is the way to go. But I've no idea how to make it work with my program. For example, I saw this example online:
void Calculate(int x, int y, int* prod, int* quot)
{
*prod = x*y;
*quot = x/y;
}
int x = 10,y = 2, prod, quot;
Calculate(x, y, &prod, ")
How does the above program actually "return"? How do I print the return values to the console?
#include "stdio.h"
void largest_two( int numbers[], int len, int *largest, int *next_largest){
int i, temp;
*largest = numbers[0];
*next_largest = numbers[1];
if(*largest < *next_largest){
temp = *next_largest;
*largest = *next_largest;
*next_largest = temp;
}
for (i=0; i<sizeof(numbers); i++) {
if(numbers[i]>= *largest){
*largest = numbers[i];
*next_largest = *largest;
}
else if ( numbers[i] > *next_largest){
*next_largest = numbers[i];
}
}
}
int main() {
int numbers[] = {3, 1, 2, 3, 6, 2, 8, 0, 0, 0};
int len = 3;
int largest, next_largest;
//==>??? printf("%d %d", largest_two(numbers, len, &largest, &next_largest));
}
Sides' from the pointer issues (you should read a tutorial / book on them), your main problem is that you're attempting to print the single return value of a function with return type void which means it won't return at all.
Your code:
int main() {
int numbers[] = {3, 1, 2, 3, 6, 2, 8, 0, 0, 0};
int len = 10; // sizeof(numbers)
int largest, next_largest;
largest_two(numbers, len, &largest, &next_largest);
printf("%d %d", largest, next_largest);
}
Keep in mind this is still not entirely correct, but it does adress your problem of printing the numbers.
Also, passing len means you shouldn't do this for (i=0; i<sizeof(numbers); i++) but this instead for (i=0; i<len; i++)
Firstly, this line:
for (i=0; i<sizeof(numbers); i++)
is not correct. You want this to be instead:
for (i=0; i<len; i++)
which should be passed to largest_two() as sizeof numbers/sizeof numbers[0], which is the actual length of the array.
I also suggest setting largest and next_largest to INT_MIN from <limits.h>, and then finding these values from their. It seems you are also having trouble with pointers, and it would be best to use them only when needed.
Here is an example which simplifies your approach, which finds the largest and second largest element in one loop of the array. It also only uses pointers when needed.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#define ARRAYSIZE(x) (sizeof x/sizeof x[0])
void largest_two(int numbers[], size_t len, int *largest, int *next_largest);
int main(void) {
int numbers[] = {3, 1, 2, 3, 6, 2, 8, 0, 0, 0};
int largest, next_largest;
largest_two(numbers, ARRAYSIZE(numbers), &largest, &next_largest);
printf("largest = %d\nnext_largest = %d\n", largest, next_largest);
}
void largest_two(int numbers[], size_t len, int *largest, int *next_largest) {
int max, smax;
max = smax = INT_MIN;
for (size_t i = 0; i < len; i++) {
if (numbers[i] > max) {
smax = max;
max = numbers[i];
} else if (numbers[i] > smax && numbers[i] < max) {
smax = numbers[i];
}
}
*largest = max;
*next_largest = smax;
}
Output:
largest = 8
next_largest = 6
Second dataset:
int numbers[] = {3, 1, 6, 3, 6, 2, 8, 0, 8, 7};
Output:
largest = 8
next_largest = 7
I want to decrement a pointer to the last element of an array and check for the condition that if the value of the pointer was smaller than 5, do nothing and go to the next round of loop and if not, that is if the value is equal or bigger than 5, print the value. So, for the array in the example, I want only 6 to be printed, that is the first encounter of a value equal or bigger than 5. I tried the code below but while being compiled with no error, it doesn't print any value. I'd appreciate your comments on this.
#include<stdio.h>
//The is a C program to decrement an array from the last element to the first.
int x[11] = {5, 6, -4, -3, -2, -1, 4, 3, 2, 1, -2};
int *lastElem, count;
int main (void) {
lastElem = &x[10];
for (count = 0; count < 11; count++)
if (abs(*lastElem) < 5)
continue;
else
printf("%d\n", *lastElem--);
return 0;
}
There is a problem in your decrement logic. If the value is less than 5, you're missing the decremet.
check the below code.
#include<stdio.h>
//The is a C programme to decrement an array from the last element to the first.
int x[11] = {5, 6, -4, -3, -2, -1, 4, 3, 2, 1, -2};
int *lastElem, count;
int main (void) {
lastElem = &x[10];
for (count = 0; count < 11; count++)
{
if (*lastElem >= 5)
{
printf("%d\n", *lastElem);
break ;
}
lastElem--;
}
return 0;
}
EDIT:
As you modified your question to include the absolute value comparions, the changes are like below.
Note : When making some major changes [which will change the behaviour and output] to the original question asked, do make a note of that, and if possible, mention the edit properly.
#include<stdio.h>
#include <stdlib.h>
//The is a C programme to decrement an array from the last element to the first.
int x[11] = {5, -6, -4, -3, -2, -1, 4, 3, 2, 1, -2};
int *lastElem, count;
int main (void) {
lastElem = &x[10];
for (count = 0; count < 11; count++)
{
if ( abs(*lastElem) >= 5)
{
printf("%d\n", *lastElem);
break;
}
lastElem--;
}
return 0;
}
You never assign another address to lastElem than the inital value (that is the 10th element). Also, if you want to go backwards, set count to 10 and let it count to 0. In each loop you have to assign &x[count] to lastElem (or decrement it, as it is a pointer and the address will be decremented according to the object it points to).
The line printf("%d\n", *lastElem--); is not always executed it is only executed when abs(*lastElem) >= 5. This is how you should do it
#include<stdio.h>
//The is a C programme to decrement an array from the last element to the first.
int x[11] = {5, 6, -4, -3, -2, -1, 4, 3, 2, 1, -2};
int *lastElem, count, value;
int main (void)
{
lastElem = &x[10];
for (count = 0; count < 11; count++)
{
value = *(lastElem--);
if (value < 5)
continue;
printf("%d\n", value);
break;
}
return 0;
}
This will do it with continue.
Here is the only correct code among presented here in other answers that does the task.:)
In fact you need a program that searches backward an alement of an array that satisfies a given condition. And if there is such an element then to output it.
#include <stdio.h>
#include <stdlib.h>
int main( void )
{
int a[] = { 5, 6, -4, -3, -2, -1, 4, 3, 2, 1, -2 };
const size_t N = sizeof( a ) / sizeof( *a );
int *first = a, *last = a + N;
while ( first != last && ( unsigned int )abs( *( last - 1 ) ) < 5 ) --last;
if ( first != last ) printf( "%d\n", *--last );
return 0;
}
The output is
6
Below there is demonstrated a general approach for such tasks
#include <stdio.h>
#include <stdlib.h>
int * find_backward( const int a[], size_t n, int ( *predicate )( int ) )
{
const int *first = a, *last = a + n;
while ( first != last && !predicate( *( last -1 ) ) ) --last;
return ( int * )last;
}
int is_greater_or_equal_to_5( int x )
{
return 5 <= ( unsigned int )abs( x );
}
int main( void )
{
int a[] = { 5, 6, -4, -3, -2, -1, 4, 3, 2, 1, -2 };
const size_t N = sizeof( a ) / sizeof( *a );
int *target = find_backward( a, N, is_greater_or_equal_to_5 );
if ( target != a ) printf( "%d\n", *--target );
return 0;
}
Using this approach you can use any integer arrays (even with zero size) and any conditions that are set by means of predicates.
For example if you want to find the last element of an array that is divisible by 3 you can write
#include <stdio.h>
#include <stdlib.h>
int * find_backward( const int a[], size_t n, int ( *predicate )( int ) )
{
const int *first = a, *last = a + n;
while ( first != last && !predicate( *( last -1 ) ) ) --last;
return ( int * )last;
}
int divisible_by_3( int x )
{
return x % 3 == 0;
}
int main( void )
{
int a[] = { 5, 6, -4, -3, -2, -1, 4, 3, 2, 1, -2 };
const size_t N = sizeof( a ) / sizeof( *a );
int *target = find_backward( a, N, divisible_by_3 );
if ( target != a ) printf( "%d\n", *--target );
return 0;
}
The output is
3
Take into account that this function allows also to deal with constant arrays.:)