Decrementing an array and print a value if condition met - c

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.:)

Related

Im trying to find the max and min value and its respective index. However I cant get the indexmin

Find the minimum element of the array and its corresponding index.
I can't get the the minimum index to work. Do I add else statement under each if statement?
#include<stdio.h>
int main()
{
int array[10]={1,2,3,4,5,6,7,8,9,10} , i;
**//finding max and min, and its respective index**
int max = array[0] , min = array[0];
int indmin , indmax;
for( i = 0 ; i < 10 ; i++ )
{
if(array[i] > max)
{
max = array[i];
indmax = i;
}
if(array[i] < min)
{
min = array[i];
indmin = i;
}
}
//print the max and min value and its indexs
printf("\nMaximum element is %d\t index is %d", max , indmax);
printf("\nMinimum element is %d\t index is %d", min , indmin);
}
Initialize indmin and indmax. When defining the array leave out the size so it's derived from the data. When iterating over the array use sizeof(array) / sizeof(*array) to let compiler determine the size of the array instead of hard-coding it. Minimize scope of variable i. Use a function to print output for less duplication:
#include <stdio.h>
void print(const char *prompt, int value, int index) {
printf("%s element is %d\t index is %d\n", prompt, value, index);
}
int main() {
int array[]={1,2,3,4,5,6,7,8,9,10};
int min = array[0];
int indmin = 0;
int max = array[0];
int indmax = 0;
for(int i = 0; i < sizeof(array) / sizeof(*array); i++) {
if(array[i] > max) {
max = array[i];
indmax = i;
}
if(array[i] < min) {
min = array[i];
indmin = i;
}
}
print("Maximum", max, indmax);
print("Minimum", min, indmin);
}
You could refactor this by creating a struct to keep the value and index together:
#include <stdio.h>
struct value_index {
int value;
int index;
};
void print(const char *prompt, struct value_index *vi) {
printf("%s element is %d\t index is %d\n", prompt, vi->value, vi->index);
}
int main() {
int array[]={1,2,3,4,5,6,7,8,9,10};
struct value_index min = { array[0], 0 };
struct value_index max = { array[0], 0 };
for(int i = 0; i < sizeof(array) / sizeof(*array); i++) {
if(array[i] > max.value) {
max.value = array[i];
max.index = i;
}
if(array[i] < min.value) {
min.value = array[i];
min.index = i;
}
}
print("Maximum", &max);
print("Minimum", &min);
}
Or you could realize that you only need the original array along with the two indices. To make my version even better than #Fe2O3's answer, I used a macro to make mine smaller (and if bait works then I will claim mine is easier to read) :-)
#include <stdio.h>
void print(const char *prompt, int *arr, int index) {
printf("%s element is %d\t index is %d\n", prompt, arr[index], index);
}
int main() {
int array[]={1,2,3,4,5,6,7,8,9,10};
int indmin = 0;
int indmax = 0;
for(int i = 0; i < sizeof(array) / sizeof(*array); i++) {
#define CMP_AND_SET(OP, V) if(array[i] OP array[V]) V = i
CMP_AND_SET(<, indmin);
CMP_AND_SET(>, indmax);
#unset CMP_AND_SET
}
print("Maximum", array, indmax);
print("Minimum", array, indmin);
}
Building on #Fe2O3's branchless idea combined with an initialized array which I find to compact and quite readable:
indmin = (int[]) { indmin, i }[array[i] < array[indmin]];
indmax = (int[]) { indmax, i }[array[i] > array[indmax]];
By using (a < b) <=> -1 * (-a > -b) you can write the last one as (note: UB if array contains INT_MIN):
indmax = (int[]) { indmax, i }[-array[i] < -array[indmax]];
I would use a local macro to reduce code duplication by using macro to generate either the first version by passing in the operator (see above) or the 2nd version by passing in a factor F:
#define MINMAX(V, F) V = (int[]) { V, i }[F * array[i] < F * array[V]]
indmin = MINMAX(indmin, 1);
indmax = MINMAX(indmax, -1);
I am totally cheating but you can shuffle the min and max elements to fixed positions within the source array. No storage overhead. This would be the opposite of branchless.
#include <stdio.h>
void print(const char *prompt, int value) {
printf("%8s = %3d\n", prompt, value);
}
int swap(int *a, int *b) {
int tmp = *a;
*a = *b;
*b = tmp;
return 0;
}
int main(void) {
int arr[] = { 1, 2, 3, 4, 42, 5, -42, 6, 7, 8, 9, 10 };
const int min = 0;
const int max = sizeof arr/sizeof *arr - 1;
for(int i = 1; i < max + 1; i++ )
arr[i] < arr[min] && swap(arr + i, arr + min) ||
arr[i] > arr[max] && swap(arr + i, arr + max);
print("min", arr[min]);
print("max", arr[max]);
}
Leaving variables uninitialised is asking Demon of Hard-To-Find Bugs to co-author your code. Define variables close to where they are used to increase clarity. And, don't define more variables than you need. (Common beginner mistake to make another copy "just in case"...)
// use the spacebar to increase readability
#include <stdio.h>
int main() {
// let the compiler assign the size of an initialised array
int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
// use fewer variables
int indmin = 0, indmax = 0;
// don't compare an element (arr[0]) to itself
for( int i = 1 ; i < sizeof array/sizeof array[0]; i++ )
if( array[ i ] > array[ indmax ] )
indmax = i; // updated
else
if( array[ i ] < array[ indmin ] )
indmin = i; // updated
// don't add unnecessary braces (imho)
// this isn't the 17th century in need of needless filligree.
// use '\n' at the END of output. sometimes needed to 'flush' output buffer
printf("Maximum element is %d\t index is %d\n", array[ indmax ] , indmax);
printf("Minimum element is %d\t index is %d\n", array[ indmin ] , indmin);
return 0;
}
Maximum element is 10 index is 9
Minimum element is 1 index is 0
EDIT:
So, there's a friendly competition going on in this question... :-)
How's this:
#include <stdio.h>
int main() {
// let the compiler assign the size of an initialised array
// use shorter names to expose operations (not lengthy variable names)
int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int iMin = 0, iMax = 0;
// don't compare an element to itself
for( int i = 1; i < sizeof arr/sizeof arr[0]; i++ ) {
// use "branchless" coding for speed.
int n = arr[i] > arr[iMax];
iMax = n*i + !n*iMax;
n = arr[i] < arr[iMin];
iMin = n*i + !n*iMin;
}
// reduce duplication of static data
char *fmt = "%s element is %d\t index is %d\n";
printf( fmt, "Maximum", arr[ iMax ], iMax );
printf( fmt, "Minimum", arr[ iMin ], iMin );
return 0;
}
Same output.
Ball's in your court #Allan :-)
EDIT:
There has been an advance on the last offering that needs to be addressed...
Here we go whole-hog, splurging-out with a third 'container' (mm[0]) to catch all those indexes that satisfy neither conditional ('<' & '>'). AND, a 4th 'container' (mm[3]) that doesn't change from being initialised to 0, the index of the 1st element. Besides being cryptic (not advised), this may-or-may-not be more expensive with its multiple array offset calculations... But, it's fun to look at...
#include <stdio.h>
int main() {
// added two elements to show 0 and nElem are not 'flukes'
// this really does find and report the min/max values
int arr[] = { 1, 2, 3, 4, 42, 5, -42, 6, 7, 8, 9, 10 };
int i, mm[1 + 2 + 1] = { 0 };
// assign 'i' to mm[ 0 or 1 or 2 ]. 0=latest, 1=max, 2=min, (3 unaffected)
for( i = 1; i < sizeof arr/sizeof arr[0]; i++ )
mm[ (arr[i] > arr[mm[1]]) + 2*(arr[i] < arr[mm[2]]) ] = i;
mm[ 0 ] = i-1; // always pick up the last index. Thanks #A Wind!
// now... this is getting silly!!
char *fmt = "%5s = %3d # arr[%d]\n";
char *type[] = { "last", "max", "min", "first" };
i = 3; do printf( fmt, type[i], arr[ mm[i] ], mm[i] ); while( --i >= 0 );
return 0;
}
first = 1 # arr[0]
min = -42 # arr[6]
max = 42 # arr[4]
last = 10 # arr[11]
Y'know... This might be interesting to try to apply to 3-way branching as is needed for binary searching; determining '<', '=' or '>'... Hmmm...
EDIT: (another variation on a theme at the suggestion of a worthy competitor :-)
#include <stdio.h>
int main() {
struct {
char *label;
int ind;
} mm[] = {
{ "last" },
{ "maximum" },
{ "minimum" },
{ "first" },
};
int i, arr[] = { 1, 2, 3, 4, 42, 5, -42, 6, 7, 8, 9, 10 };
for( i = 1; i < sizeof arr/sizeof arr[0]; i++ )
mm[ (arr[i] > arr[mm[1].ind]) + 2*(arr[i] < arr[mm[2].ind]) ].ind = i;
mm[ 0 ].ind = --i; // always pick up the last index. Thanks #A Wind!
for( i = sizeof mm/sizeof mm[0]; --i >= 0; /* space for rent */ )
printf( "%8s = %3d # arr[%d]\n", mm[i].label, arr[ mm[i].ind ], mm[i].ind );
return 0;
}
EDIT:
Trying to cover ALL the bases, here are three more ways to skin a cat
/* Minimalist */
#include <stdio.h>
int main() {
int mm[3] = { 0 },
arr[] = { 1, 2, 3, 4, 42, 5, 6, 7, 8, 9, 10 },
i = sizeof arr/sizeof arr[0];
while( --i )
mm[ 2*(arr[i] > arr[mm[2]]) + (arr[i] < arr[mm[1]]) ] = i;
char *fmt = "arr[%d] = %3d M%simum\n";
printf( fmt, mm[1], arr[mm[1]], "in" );
printf( fmt, mm[2], arr[mm[2]], "ax" );
return 0;
}
/* Recursive - for brevity, excluding the index; just reporting two values */
#include <stdio.h>
int amin( int a[], int i ) { // NB: "amin", not "main"
int j = --i ? amin( a, i ) : i;
return (a[j]<a[i])*j + (a[j] > a[i])*i;
}
int amax( int a[], int i ) {
int j = --i ? amax( a, i ) : i;
return (a[j]>a[i])*j + (a[j]<a[i])*i;
}
int main() {
int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, },
sz = sizeof arr/sizeof arr[0];
char *fmt = "M%simum: %3d\n";
printf( fmt, "in", arr[ amin(arr, sz) ] );
printf( fmt, "ax", arr[ amax(arr, sz) ] );
return 0;
}
/* And, simply brute force using a library function */
#include <stdio.h>
#include <stdlib.h>
int cmp( const void *a, const void *b ) { return *(int*)a - *(int*)b; }
int main() {
int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 },
sz = sizeof arr/sizeof arr[0];
qsort( arr, sz, sizeof arr[0], cmp );
char *fmt = "M%simum: %3d\n";
printf( fmt, "in", arr[ 0 ] );
printf( fmt, "ax", arr[ --sz ] ); // again, thanks to #A Wind
return 0;
}
Many ways to skin a cat.

Print prime numbers using pointer arithmetic

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' );
}

writing function with pointers in c

I wrote this code :
#include <stdio.h>
void transpose(int *Al[]){
int x=0;
int z=0;
int k=1;
while (*Al[z] != "\0") {
int c=*Al[z];
if (c>x)
x=c;
z++;
}
printf("%d ",x);
for(int o=0;o<6;o++){
for(int i=0 ;i<x;i++ ) {
int *p = Al[i];
int l=*p;
if(k<l)
printf("%d ",*(p+k));
else
printf(" ");
}
k++;
printf("\n");
}
}
int main() {
int A[] = {5, -5, 14, 5, 2};
int B[] = {3, 6, 11};
int C[] = {4, 1, -3, 4};
int D[] = {6, 2, 7, 1, 8, 2};
int E[] = {2, 15};
int F[] = {3, 4, -2};
int *All[] = {A, B, C, D, E, F, NULL};
transpose(All);
}
The function gets an array that points to different array I need to print the arrays using pointers
the output should be :
-5 6 1 2 15 4
14 11 -3 7 -2
5 4 1
2 8
2
But this code doesn't print anything.
Also the arrays that it points at the first value is the size of the array.
I tried this :
void transpose(int *Al[]){
int x=0;
int z=0;
int k=1;
for(int o=0;o<5;o++){
for(int i=0 ;i<6;i++ ) {
int *p = Al[i];
int l=*p;
if(k<l)
printf("%d ",*(p+k));
else
printf(" ");
}
k++;
printf("\n");
}
}
It worked only I need to replace the five and six in the loop
Five is the biggest size of all he arrays -1 so I will know how many lines to print and six to how many arrays in All so I can know how many colums I should print. Is there a solution for this?
The condition in the while loop
while (*Al[z] != "\0") {
does not make a sense. The expression *Al[z] has the type int while the string literal "\0" has the type char *.
Also it is unclear why there is present the magic number 6 in this loop
for(int o=0;o<6;o++){
There is no need to calculate explicitly the number of columns because you have a sentinel value equal to NULL.
I can suggest for example the following solution
#include <stdio.h>
void transpose( int * Al[] )
{
int rows = 0;
for ( int **p = Al; *p != NULL; ++p )
{
if ( rows < **p ) rows = **p;
}
if ( rows ) --rows;
for ( int i = 0; i < rows; i++ )
{
for ( int **p = Al; *p != NULL; ++p )
{
if ( i + 1 < **p ) printf( "%2d ", *( *p + i + 1 ) );
else printf( " " );
}
putchar( '\n' );
}
}
int main(void)
{
int A[] = {5, -5, 14, 5, 2};
int B[] = {3, 6, 11};
int C[] = {4, 1, -3, 4};
int D[] = {6, 2, 7, 1, 8, 2};
int E[] = {2, 15};
int F[] = {3, 4, -2};
int *All[] = { A, B, C, D, E, F, NULL };
transpose( All );
return 0;
}
The program output is
-5 6 1 2 15 4
14 11 -3 7 -2
5 4 1
2 8
2

Problem searching for a value in a matrix

I wanted to make a function that checks if a value exists in a matrix or not by giving (the matrice + the value I want to check + the line) as parameters and I'm getting an error on the transtype from an integer to a pointer. Please I need a help as soon as possible, thank you:)
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
bool Search(int *Mat[4][4], int val, int numLigne) {
int i;
for (i = 0; i <= 4; ++i) {
if (Mat[numLigne][i] == val)
return 1;
else
return 0;
}
}
int main() {
int Mat[4][4] = {
{ 1, 2, 3, 4 },
{ 5, 6, 7, 8 },
{ 9, 10, 11, 12 },
{ 13, 14, 15, 16 }
};
int p;
p = Search(Mat[4][4], 5, 1);
printf("The number is: %d", p);
return 0;
}
Plenty problems
int *Mat[4][4] it is the array of pointers to int. Not the pointer to array. You want int Mat[4][4] here
Search(Mat[4][4], you do not pass the pointer to the function only the integer value which is taken outside the array bounds. 2 UBs in one call. You want Search(Mat, here
for( i=0; i<=4; ++i ) it is wrong as indexes in your array are from 0 to 3, and you integrate to 4. You want for( i=0; i<4; ++i )
This code
for( i=0; i<=4; ++i )
{
if(Mat[numLigne][i] == val )
return 1;
else
return 0;
}
is equivalent to:
if(Mat[numLigne][0] == val )
return 1;
else
return 0;
You will stop on the index 0 as you return on both conditions.
I think you need to read the pointer and array chapters of your favourite C book. You need to read about iterations, ifs and functions.
There are multiple problems in your code:
the prototype for Search should be bool Search(int Mat[4][4], int value, int row); or simply bool Search(int Mat[][4], int value, int row);. as posted you declare Mat to be a matrix of pointers to int.
the loop for (i = 0; i <= 4; ++i) should stop when i == 4, hence the test should be i < 4.
if the value if not found in the first column, you immediately return 0 without testing the other columns.
passing the matrix to the function is written Search(Mat, 5, 1). As posted, you attempt to pass the value of a matrix element outside the matrix.
Search returns a boolean indicating if the row contains the value, but the column number is not returned. It would be better to return the column number and return -1 if the value is not found.
Here is a modified version:
#include <stdio.h>
int Search(int Mat[4][4], int val, int row) {
for (int i = 0; i < 4; ++i) {
if (Mat[row][i] == val)
return i;
}
return -1; // not found
}
int main() {
int Mat[4][4] = {
{ 1, 2, 3, 4 },
{ 5, 6, 7, 8 },
{ 9, 10, 11, 12 },
{ 13, 14, 15, 16 }
};
int col = Search(Mat, 5, 1);
if (col >= 0)
printf("The value %d is at position Mat[%d][%d]\n", 5, 1, col);
else
printf("The value %d is not present in row %d of Mat\n", 5, 1);
return 0;
}

count issue in c (visual studio)

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 )
{
//...
}

Resources