I'm trying to make a function that identifies the maximum value in an array and calculate the sum of each time it appears. That's fine but the problem is that I need to make the function args the size of the array and the array itself.
This is what I've come up this far:
int sum(int a, int size)
{
int i, max, output=0;
//checking every index for max value
for(i=0;i<=tam;i++){
if(i==1){
//setting max on the first index
max=a[i];
}else{
if(a[i]>max){
a[i]=max;
}
}
}
//making the sum
for(i=0;i<size;i++){
if(a[i]==max);
output=output+max;
}
printf("%d", output);
}
The argument "a" is the array and the size is the size of the array. I get errors saying "a" is neither array nor pointer nor vector.
Any help is apreciated.
Replace int sum(int a, int size) to int sum(int *a, int size) or int sum(int a[], int size)
This function declaration
int sum(int a, int size);
declares a function with two parameters of the type int. If you mean that the first parameter should specify a one-dimensional array then the function declaration will look like
int sum(int a[], int size);
or
int sum( int *a, int size);
because a parameter having an array type is adjusted by the compiler to pointer to the array element type.
Also your function returns nothing though its return type is not void.
Moreover the function uses undeclared variables as for example the variable tam.
And if an array has size elements then the valid range of indices is [0, size ).
Also the function should not change the passed array. And to avoid integer overflow the return type should be long long int.
Also the function should not output any message. It is the caller of the function that decides whether to output a message.
The function can look the following way as it is shown in the demonstrative program below.
#include <stdio.h>
long long int sum( const int a[], size_t n )
{
long long int total = n == 0 ? 0 : a[0];
size_t max = 0;
for ( size_t i = 1; i < n; i++ )
{
if ( a[max] < a[i] )
{
total = a[i];
max = i;
}
else if ( !( a[i] < a[max] ) )
{
total += a[max];
}
}
return total;
}
int main(void)
{
int a[] = { 2, 8, 8, 9, 7, 3, 8, 1, 9 };
const size_t N = sizeof( a ) / sizeof( *a );
printf( "The sum of elements with the maximum value is %lld\n", sum( a, N ) );
return 0;
}
The program output is
The sum of elements with the maximum value is 18
#include<stdio.h>
#include<stdlib.h>
int sum(int *a, int size);
int main()
{
int *a=(int*)malloc(10*sizeof(int));
for(int i=0;i<10;i++)
a[i]=i+1;
sum(a,10);
}
int sum(int *a, int size)
{
int i, max, output=0;
//checking every index for max value
for(i=0;i<size;i++){
if(i==1){
//setting max on the first index
max=a[i];
}else{
if(a[i]>max){
a[i]=max;
}
}
}
//making the sum
for(i=0;i<size;i++){
if(a[i]==max);
output=output+max;
}
printf("%d", output);
}
Well, you can do it in just one pass, as when you identify a new maximum, the accumulated sum of the last is no longer valid (it refers not to the biggest number, but to one smaller)
There's something in your code that is weird... you start the loop at 0, and then compare if (i == 1) which I guess is a mistake (shouldn't it be 0?), as you should want to check if you are at the first (and not at the second cell) to do the initialization of max. Anyway, there's a clever way to do is to initialize max to the minimum number you can have (and for an int you have that value in <limits.h> as the constant INT_MIN). I'll show you now one possible source code to your problem (taken from yours, but changed some variables and added others to show you that in one pass you can do a lot of work:
#include <stdio.h>
#include <limits.h>
/* pretty format of output with location of trace in source file
*/
#define F(_fmt) __FILE__":%d:%s: "_fmt,__LINE__,__func__
/* to pass an array, just declare it as below. The array size is
* unspecified because your don't know it before calling sum,
* and this is the reason to pass the array size. */
int sum(int a[], int size)
{
int i, pos0 = -1, pos1 = -1, max = INT_MIN, output=0;
/* checking every index for max value, and output, you made
* an error here and used tam instead of size. */
for(i = 0; i <= size; i++){
if (a[i] > max) { /* if greater than max */
pos0 = i; /* save position as first */
max = a[i]; /* save max value */
output = max; /* initialize output to max */
} else if (a[i] == max) { /* if equal to max */
pos1 = i; /* save position as last */
output += max; /* add to output */
} /* else nothing */
}
/* print all the values we got */
printf(F("pos0 = %d, pos1 = %d, max = %d, output = %d\n"),
pos0, pos1, max, output);
return output; /* return the requested sum */
}
int list[] = { 3, 2, 5, 6, 5, 4, 7, 3, 7, 4, 7, 2, 1, 6, 2 };
/* max is located ^ ^ ^ in these positions
* 6 8 10 */
/* the following macro gives us the size of the array list by
* dividing the size of the complete array by the size of the
* first element. */
#define n_list (sizeof list / sizeof list[0])
int main()
{
printf(F("result = %d\n"), sum(list, n_list));
}
which should output (if the program is named test from test.c):
$ test
test.c:23:sum: pos0 = 6, pos1 = 10, max = 7, output = 21
test.c:34:main: result = 21
$ _
Related
How do I return the last element in an array? I thought this function would work, as it worked for a similar function that returned the first element.
int END(int arr[]) {
int last;
size_t s = sizeof(arr) / sizeof(arr[0]);
if (s != 0) {
last = arr[s - 1];
return last;
} else {
return -1 ; //END(arr);
}
}
int END(int arr[]) is adjusted to int END(int* arr), since you can't pass arrays as arguments in C. This means that sizeof(arr) is sizeof(int*), and your calculation for s is wrong.
You can use a macro for this, as the macro argument won't be turned into a pointer implicitly:
#define END(ARR) (ARR)[(sizeof(ARR) / sizeof((ARR)[0])) - 1u]
(Note that there are no arrays of size 0, so your -1 case is redundant)
You cannot use sizeof inside a function because sizeof(arr) will return the size of the pointer which is generally 8 bytes on a x86_64 architecture. I would not use -1 is an error value because -1 can be an element of the given array. I would prefer the C++ way of npos, returning the maximum value of the data type according to the system architecture.
I would recommend you to get the length of the array as a parameter of the function. Like this:
#include <stdio.h>
#include <limits.h>
int END(int *arr, size_t length); // fix prototype error
/*
#brief Returns the last element of the array `arr`.
#param arr array
#param length array's length
#returns If `arr` is NULL or empty returns INT_MAX, otherwise the last element.
*/
int END(int *arr, size_t length)
{
if (!arr || length == 0) // if arr is NULL
return INT_MAX;
else
return arr[length - 1]; // 0 based indexing system in C
}
int main(void)
{
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
size_t length = sizeof(arr) / sizeof(*arr);
printf("Last element of the array: %d\n", END(arr, length));
return 0;
}
Output:
Last element of the array: 10
I'm a newbie both here in stackoverflow and both in the world of programming.
Today i was solving some exercise about recursion, and one of these asked to write a recursive function for finding minimum element of an array.
After many tries, I have finally wrote this working code, but i want to ask you if this is a "good" code. I mean, the fact it's working aside, is it written well? There's something that should be changed? And, above all, there's a way to make this functions working well without declaring that global int "min"? :)
Here's the code:
#include <stdio.h>
int recursiveMinimum(int array[], size_t size);
int min = 1000;
int main(void) {
int array[] = {55, 5, 1, 27, 95, 2};
printf("\nMinimum element of this array is: %d\n\n",
recursiveMinimum(array, 6));
}
int recursiveMinimum(int array[], size_t size) {
if (size == 1) {
return min;
} else {
if (array[size] <= min) min = array[size];
return min = recursiveMinimum(array, size - 1);
}
}
It is a bad idea when a function depends on a global variable.
But in any case your function is incorrect and invokes undefined behavior.
In the first call of the function this if statement
if (array[size] <= min) min = array[size];
trying to access memory outside the passed array because the valid range of indices is [0, size).
Also the array can contain all elements greater than the initial value of the global variable
int min = 1000;
And the function may not be called a second time because the value of the variable min is unspecified.
The function should return the index of the minimal element in the array. In general the user can pass the second argument equal to 0. In this case again the function will invoke undefined behavior if you will try to return a non-existent element of an empty array.
The function can be declared and defined the following way
size_t recursiveMinimum( const int a[], size_t n )
{
if ( n < 2 )
{
return 0;
}
else
{
size_t min1 = recursiveMinimum( a, n / 2 );
size_t min2 = recursiveMinimum( a + n / 2, n - n / 2 ) + n / 2;
return a[min2] < a[min1] ? min2 : min1;
}
}
Here is a demonstration program
#include <stdio.h>
size_t recursiveMinimum( const int a[], size_t n )
{
if (n < 2)
{
return 0;
}
else
{
size_t min1 = recursiveMinimum( a, n / 2 );
size_t min2 = recursiveMinimum( a + n / 2, n - n / 2 ) + n / 2;
return a[min2] < a[min1] ? min2 : min1;
}
}
int main( void )
{
int a[] = { 55, 5, 1, 27, 95, 2 };
const size_t N = sizeof( a ) / sizeof( *a );
size_t min = recursiveMinimum( a, N );
printf( "\nMinimum element of this array is: %d at the position %zu\n",
a[min], min );
}
The program output is
Minimum element of this array is: 1 at the position 2
Pay attention to that the first parameter has the qualifier const because the passed array is not being changed within the function. And to decrease the number of recursive calls the function calls itself for two halves of the array.
Recursion works by reducing the size at the call to the next iteration and comparing the result of the call with the current value and return the lower of the 2.
As recursion stop you can simply return the first element
int recursiveMinimum(int array[], size_t size) {
if (size == 1) return array[0];
int min_of_rest = recursiveMinimum(array, size - 1);
if (array[size - 1] <= min_of_rest) return array[size - 1];
return min_of_rest;
}
Full example: https://godbolt.org/z/sjnh8sYz3
In the past, we used to implement it with pointers, KR-C style.
Using pointers in a harsh way was a mean to deal with inefficiency of compilers at that time.
Not sure it is considered good practice now. An example is provided hereafter.
Anyway, it would be better (easier and more efficient) to implement it in a non recursive manner.
#include <stdio.h>
void recursiveMinimum(int *array, size_t size, int *min) {
if (size == 0) return;
if (*array < *min) *min = *array;
recursiveMinimum (array+1, size-1, min);
return;
}
int main(void) {
int array[] = {55, 5, 1, 27, 95, 2};
size_t size = sizeof(array)/sizeof(*array);
int min = array[0];
recursiveMinimum (array, size, &min);
printf("\nMinimum element of this array is: %d\n", min);
return 0;
}
So I have a task in my training that sounds like this:
Write a subprogram that will recursively find the maximum element from an array and also write the main function to call it.
What I failed to fully understand is what recursion is. I wanted to ask you guys if my code is recursive or not. And if not what changes should I make/ what recursion really means?
#include <stdio.h>
int find_maximum(int[], int);
int main() {
int c, array[100], size, location, maximum;
printf("Input number of elements in array\n");
scanf("%d", &size);
printf("Enter %d integers\n", size);
for (c = 0; c < size; c++)
scanf("%d", &array[c]);
location = find_maximum(array, size);
maximum = array[location];
printf("Maximum element location = %d and value = %d.\n", location + 1, maximum);
return 0;
}
int find_maximum(int a[], int n) {
int c, max, index;
max = a[0];
index = 0;
for (c = 1; c < n; c++) {
if (a[c] > max) {
index = c;
max = a[c];
}
}
return index;
}
Thank you all for your time!
Problems that are well-suited to recursion can be broken down into smaller, simpler subproblems. This is one of the things that gives recursion its power. When trying to use recursion to solve a problem, it usually seems best to try to break the problem down into simpler subproblems in finding your way to a solution.
You might notice that in finding the maximum value stored in an array, it is either the value of the first element, or the maximum value of the remaining elements. This breaks the problem into two parts: if the first element is larger than any remaining elements, you are done; otherwise, you must continue and see if the next element is larger than the remaining elements. In code, this might look like:
int max_in(size_t rest_sz, int *rest)
{
int curr_val = rest[0];
if (rest_sz == 1) {
return curr_val;
}
int max_in_rest = max_in(rest_sz-1, rest+1);
return curr_val > max_in_rest ? curr_val : max_in_rest;
}
Here, there is a base case: if rest_sz is 1, there is no need to look further; the value of first element (curr_val = rest[0]) is the maximum, and that value is returned. If the base case is not satisfied, execution of the function continues. max_in_rest is the result from the recursive function call max_in(rest_sz-1, rest+1). Here rest_sz-1 indicates the number of elements remaining in the portion of the array indicated by rest+1. In the new function call, the base case is met again, and eventually this case will be true since rest_sz is decremented with each recursive call. When that happens, the value of curr_val in the current stack frame will be returned; note that this value is the value of the last element in the array. Then, when the function returns to its caller, max_in_rest in that frame will get the returned value, after which the larger of curr_val or max_in_rest is returned to the previous caller, and so on, until finally control is returned to main().
Using pencil and paper to diagram each function call, the values of its variables, and what is returned would help to understand exactly how this recursion works.
You can apply the same method to solving the problem of finding the index of the maximum value of an array. In this case, if the value of the first element is greater than the value of any remaining elements, then the index of the maximum element is the index of the first element; otherwise the index of the maximum element is the index of the maximum value of the remaining elements. In code, this might look like:
size_t find_max_r(int arr[], int *rest, size_t rest_sz, size_t curr_ndx)
{
if (rest_sz == 1) {
return curr_ndx;
}
int curr_val = arr[curr_ndx];
size_t max_in_rest_ndx = find_max_r(arr, rest+1, rest_sz-1, curr_ndx+1);
int max_in_rest = arr[max_in_rest_ndx];
return curr_val >= max_in_rest ? curr_ndx : max_in_rest_ndx;
}
There is just a little more information to keep track of this time. Here, if the base case is satisfied, and rest_sz is 1, then there is no reason to look further, the current index curr_ndx is the index of the maximum value. Otherwise, find_max_r() is recursively called, with rest incremented to point to the remaining elements of the array, and rest_sz suitably decremented. This time, curr_ndx is keeping track of the current index with respect to the original array, and this value is passed into each function call; also, a pointer to the first element of the original array, arr, is passed into each function call so the index value curr_ndx can access the values from the original array.
Again, when the base case is reached, the current position in the array will be the end of the array, so the first elements to be compared in the return statement will be towards the end of the array, moving towards the front of the array. Note that >= is used here, instead of > so that the index of the first maximum value is returned; if you instead want the index of the last maximum value, simply change this to >.
Here is a complete program. Note the use of the helper function find_max() to call the recursive function find_max_r(), which allows the caller to use a function with the same signature that the posted code uses (except for the use of size_t types, which is really the correct type for array indices):
#include <stdio.h>
int max_in(size_t sz, int *rest);
size_t find_max(size_t sz, int arr[]);
size_t find_max_r(int arr[], int *rest, size_t rest_sz, size_t curr_ndx);
int main(void)
{
int array[] = { 2, 7, 1, 8, 2, 5, 1, 8 };
size_t array_sz = sizeof array / sizeof array[0];
int max_val = max_in(array_sz, array);
printf("Maximum value is: %d\n", max_val);
size_t max_ndx = find_max(array_sz, array);
printf("Maximum value index: %zu\n", max_ndx);
return 0;
}
int max_in(size_t rest_sz, int *rest)
{
int curr_val = rest[0];
if (rest_sz == 1) {
return curr_val;
}
int max_in_rest = max_in(rest_sz-1, rest+1);
return curr_val > max_in_rest ? curr_val : max_in_rest;
}
size_t find_max(size_t sz, int arr[])
{
int *rest = arr;
return find_max_r(arr, rest, sz, 0);
}
size_t find_max_r(int arr[], int *rest, size_t rest_sz, size_t curr_ndx)
{
if (rest_sz == 1) {
return curr_ndx;
}
int curr_val = arr[curr_ndx];
size_t max_in_rest_ndx = find_max_r(arr, rest+1, rest_sz-1, curr_ndx+1);
int max_in_rest = arr[max_in_rest_ndx];
return curr_val >= max_in_rest ? curr_ndx : max_in_rest_ndx;
}
Program output:
Maximum value is: 8
Maximum value index: 3
Think of calculating the maximum number in an array as the number which will be maximum of the first element and the maximum of the remaining elements of the array. Something like: max(first_elem, max(remaining_elems)).
The actual recursive function: find_max quite simple, if there is just a single element in the array, that element is returned. Otherwise, we get the maximum of the first element and the remaining elements of the array.
#include <stdio.h>
// function to find the max of 2 numbers
int max(int x, int y)
{
return (x > y) ? x : y;
}
// the recursive function
int find_max(int *p, int n)
{
if (n == 1) return *p;
return max(*p, find_max(p + 1, n - 1));
}
int main(void)
{
int arr[] = {23, 3, 11, -98, 99, 45};
printf("max: %d\n", find_max(arr, sizeof arr / sizeof arr[0]));
}
No, your code does not use recursion. Recursion is when a function calls itself, or calls another function which leads to a call to itself again.
You can change your code like this to have a recursive, stateless function that can determine the maximum value of the array.
int find_maximum(int a[], int n) {
return find_maximum_r(a, 0, n);
}
int find_maximum_r(int a[], int index, int n) {
if (index + 1 == n) {
return a[index];
}
int maxRight = find_maximum_r(a, index + 1, n);
return a[index] > maxRight ? a[index] : maxRight;
}
No, your code is recursive only if you call the function find_maximum from itself directly or indirectly.
As your function is trying to get not only the maximum value, but also the position in the array, I have modified slightly the interface to return the reference (that is, a pointer to the value) so we can infer the position of the array element directly from the subtraction of element pointers. This way, I can pass to the function the array pointer directly and the array size, and then divide the array in two halves, and applying the same function to the two halves (it can be demonstrated that if some element is the maximum value of the array, it has to be greater than or equal to each half's maximum) For the same reason, I have modified some of the variables defined in your main() function, to allow for references to be used:
max.c
#include <stdio.h>
#include <assert.h>
int *find_maximum(int a[], int n); /* return a reference pointer to the maximum value */
int main() {
int c, array[100], size, *location, /* location must be a pointer */
maximum;
printf("Input number of elements in array\n");
scanf("%d", &size);
assert(size >= 1);
printf("Enter %d integers\n", size);
for (c = 0; c < size; c++)
scanf("%d", &array[c]);
location = find_maximum(array, size);
maximum = *location; /* access to the value is granted by pointer dereference */
printf("Maximum element location = %td and value = %d.\n",
location - array, /* pointer difference gives the array position */
maximum);
return 0;
} /* main */
/* somewhat efficient recursive way of a divide and conquer method
* to get the maximum element reference. */
int *find_maximum(int a[], int n)
{
if (n == 1) return a; /* array of 1 element */
int *left = find_maximum(a, n/2), /* left half begins at a
* and has n/2 elements */
*right = find_maximum(a + n/2, (n+1)/2); /* right half begins
* at a + n/2, and
* has (n+1)/2
* elements */
return *left > *right
? left
: right;
} /* find_maximum */
As you see, I have to divide by two, but as I have arrays of any length, I have to be careful not to leave out any element in the next step. This is the reason for using an array of (n+1)/2 elements in the right half of the recursive call to the function. I include n/2 elements in the first half (rounding down), I have to include (n+1)/2 elements (rounding up) in the right half, to be sure that I include all the array elements in the two halves.
First of all, recursion means - function calling itself.
And what you've written is not recursive function. I'll post the most simple way to find biggest or largest element in an array, using recursion.
#include<stdio.h>
#define N 5
int biggest(int num[], int n, int big)
{
if(n < 0)
return big;
else
{
if(big < num[n])
big = num[n];
return biggest(num, --n, big);
}
}
int main()
{
int a[N], i;
printf("Enter %d integer number\n", N);
for(i = 0; i < N; i++)
scanf("%d", &a[i]);
printf("Biggest Element in the array: %d\n", biggest(a, N - 1, a[0]));
return 0;
}
Source: C Program To Find Biggest Element of An Array using Recursion
NO it is not recursive function
to know about recursion this link is very useful https://www.khanacademy.org/computing/computer-science/algorithms/recursive-algorithms/a/recursion/
to make a recursion function to solve your problem try this
you can try this pseudo code declare your array global and a max=0 global and size global
int find_maximum(int i)
{
if (i == size )
return max;
else if ( max < array[i])
max =array [i];
return find_maximum(i+1);
}
where i is the array index
No, your program is certainly not recursive. As the definition, recursive function must call itself with a terminating condition.
Please read TutorialsPoint about recursion in C.
Update on #JonathanLeffler's comment:
Please note that the output in the reference will overflow.
I am trying to solve two different C problems and would like some help and advice in order to better understand how C works and if I'm on the right track with these.
First problem is: To write a function that counts the number of times the value (x) appears among the first (n) elements of an array and returns that count as the frequency of x in theArray. So, an example would be if the array being passed contained the values {5, 7, 23, 8, 23, 67, 23}. And n was 7 and x was 23, then it would return a value of 3 since 23 occurs 3 times within the first 7 elements of the array.
Here is what I have so far:
#include <stdio.h>
#define SIZE 20 /* just for example - function should work with array of any size */
int frequency (int theArray[], int n, int x)
{
int i;
int count = 0;
for (i = 0; i < n; i++)
{
if (theArray[i] == x)
{
count = count++;
}
}
return (count);
}
int main(void)
{
/* hard code n and x just as examples */
int n = 12; /* look through first 12 items of array */
int x = 5; /* value to find */
int numberFrequency;
long int theArray[SIZE] = {5,2,3,4,5,6,1,2,10,5,10,12,6,8,7};
numberFrequency = frequency (theArray[SIZE], n, x);
printf ("%i", numberFrequency);
return 0;
}
Currently I'm getting a run time error message and believe it has something to do with the for loop function.
Second problem is: Write a function that raises an integer to a positive integer power. Have the function return a long int, which represents the results of calculating x to the nth power. Do not use the C pow library function and do not use recursion!
My code so far:
#include <stdio.h>
int x_to_the_n (int x, int n)
{
int i;
long int result = 1;
if (n == 0)
{
return(result);
}
else
{
for (i = 0; i < n ; ++i)
{
/* equation here - How can I make (x*x*x*x*x*x,etc...? */
result = x*(n*x);
}
}
return (result);
}
int main(void)
{
int x =4;
int n =5;
long int result;
result = x_to_the_n (x, n);
printf ("%i", result);
return 0;
}
I can't use recursion so that is out of the question. So, I thought the next best thing would be a for loop. But I'm a little stuck in how I would go about making a for loop do (xxx*x....) based on value of (n). Any help and advice would be appreciated!
In the first problem you give an element after the array as a parameter to your function.
You define a long int array, and pass it into a function expecting an int array.
long int theArray[SIZE] = {5,2,3,4,5,6,1,2,10,5,10,12,6,8,7};
should be
int theArray[SIZE] = {5,2,3,4,5,6,1,2,10,5,10,12,6,8,7};
Instead of this:
numberFrequency = frequency (theArray[SIZE], n, x);
try this:
numberFrequency = frequency (theArray, n, x);
And replace:
count = count++;
with:
count++;
(a newer version of my program is right in the end)
I need to create a program with a function that compares two arrays of integers and returns the subscript of the first place they differ.
I have to use a sentinel value to indicate the end of valid input, rather than EOF, as a file cannot have two end-of-files.
Example of my desired input and output for my program:
Input 1:
3 4 5
3 4 6
Output 1:
2
Explanation: the third values of two arrays are different, so it prints the third subscript (counting as 0,1,2).
I looked over similar issues on stackoverflow. Many errors were fixed and now it lets me to compile a program, without giving me any errors or warnings. But it blinds me because I don't understand what exactly doesn't work.
My problem that I encounter:
When I press Enter button after the first value, the program stops working.
I assume my tableDiff function is wrong, however I copied it from teacher's notes. Unless I made a typo, there shouldn't be any difference.
Here is my submitted version:
/*
* A simple program to sort numbers in the correct order
*/
#include <stdio.h>
#include <stdlib.h>
#define MAX 10 //max elements in array
#define SENTINEL -999 //indicate the end of valid input
int main () {
int tableFill(int a[], int max);
int tableDiff (const int a[], const int b[], int n, int m);
void tablePrint (const int a[], const int b[], int n, int m);
int a[MAX];
int b[MAX];
int m,n,index;
m = tableFill(a, MAX);
n = tableFill(b, MAX);
tablePrint(a,b,n,m);
index = tableDiff(a,b,m,n);
if(index==-1)
printf("Index is the same");
else
printf("Index is the different");
return 0;
}
// read values from stdin into array up to 'max' values
int tableFill(int a[], int max) {
int r; // input from scanf
int next; // next input value
int cnt = 0; // count of values read
int *ptr; //pointer
printf("Enter the numbers! \n");
while ((r=scanf("%i", &next)) == 1 && next != SENTINEL)
{
if (r == 0) //invalid input data
{
printf("Nonnumeric data entered. Please enter a number. \n");
while (getchar()!= '\n'); // flush invalid data
}
else
*ptr++=cnt;
}
if(r==1) //another value was read but the array is full
printf("Error - too many values. Array size %i.\n", max);
return ptr-a; //(ptrb - b) should return the same value
}
int tableDiff (const int a[], const int b[], int n, int m)
{
const int *ptra = a; //start for 1st array
const int *ptrb = b; //start for 2nd array
const int *endptra = a+m; //end for 1st array
const int *endptrb = b+n; //end for 2nd array
while(ptra<endptra && ptrb<endptrb && *ptra==*ptrb)
{
ptra++;
ptrb++;
}
if( ptra==endptra && ptrb==endptrb)
{
return -1;
}
else
return ptra -a; //(ptrb - b) should return the same value
}
//print all elements in array.
void tablePrint (const int a[], const int b[], int n, int m)
{
int i; //varriable to print
for (i = 0; i < n; i++)
printf ("%d ", a[i]);
printf ("\n");
}
Here is my newer version:
The program now continues to work until reaches second sentinel (works correctly).
/*
* A simple program to sort numbers in the correct order
*/
#include <stdio.h>
#define MAX 10 //max elements in array
#define SENTINEL -999 //indicate the end of valid input
int main () {
// read values from stdin into array up to 'max' values
int tableFill(int a[], int max);
//compare two arrays and returns the first subscript they differ
int tableDiff (const int a[], const int b[], int n, int m);
//print all elements in array
void tablePrint (const int a[], int n);
int a[MAX];
int b[MAX];
int m,n,index;
m = tableFill(a, MAX);
n = tableFill(b, MAX);
tablePrint(a,m);
tablePrint(b,n);
index = tableDiff(a,b,m,n);
if(index==-1)
printf("-1. Arrays are the same.");
else
printf ("\n The arrays differ at index '%d'.\n", index);
return 0;
}
// read values from stdin into array up to 'max' values
int tableFill(int a[], int max) {
int r; // input from scanf
int next; // next input value
int cnt = 0; // count of values read
int *ptr = a; //pointer
printf("Enter the numbers! \n");
while ((r=scanf("%i", &next))==0 || (next != SENTINEL))
{
if (r == 0) //invalid input data
{
printf("Nonnumeric data entered. Please enter a number. \n");
while (getchar()!= '\n'); // flush invalid data
}
else if (cnt == max) //another value was read but the array is full
printf("Error - too many values. Array size %i.\n", max);
else {
*ptr++ = next;
++cnt;
}
}
return ptr-a; //(ptrb - b) should return the same value
}
//compare two arrays and returns the first subscript they differ
int tableDiff (const int a[], const int b[], int n, int m)
{
const int *ptra = a; //start for 1st array
const int *ptrb = b; //start for 2nd array
const int *endptra = a+m; //end for 1st array
const int *endptrb = b+n; //end for 2nd array
while(ptra<endptra && ptrb<endptrb && *ptra==*ptrb)
{
ptra++;
ptrb++;
}
if( ptra==endptra && ptrb==endptrb)
{
return -1;
}
else
return ptra -a; //(ptrb - b) should return the same value
}
//print all elements in array
void tablePrint (const int a[], int n)
{
int i; //loop counter
for (i = 0; i < n; i++)
printf ("%d ", a[i]);
printf ("\n");
}
You have a number of issues in your logic. The first of which in
while ((r=scanf("%i", &next)) == 1 && next != SENTINEL)
prevents the remainder of the code within the loop from ever executing in the event a non-numeric value is entered. If r != 1, you exit the loop, not process further within it.
While not an error, function prototypes within main only works when the functions exclusively do not rely on each other. They know nothing about one another during execution. Better to move the prototypes above main.
The remainder of your logic was somewhat difficult to follow and overly complicated. When you are looking for a difference within two arrays, you only need iterate over common elements. If they have differing number of elements, you know they differ by definition starting at the first unique element. So you can whittle down your comparison code quite a bit. Something like the following is fine:
/* check if array 'a' and 'b' are the same, else return index
* of first difference, otherwise return -1 for equal arrays.
*/
int tablediff (const int *a, const int *b, int sza, int szb)
{
int i, lim = sza < szb ? sza : szb; /* limit search to common elements */
for (i = 0; i < lim; i++) /* for each common element check */
if (a[i] != b[i])
return i;
if (sza != szb) /* if size differs, arrays differ */
return lim;
return -1; /* otherwise equal */
}
You can avoid the use of a SENTINEL just by proper bounds checking. Further, while you are free to create a arrayprint function that prints 2 arrays, it is far better to create a function that prints a single array and call it twice.
Putting those pieces together, and noting you do not use anything from stdlib.h, you could do something similar to the following:
#include <stdio.h>
#define MAX 10 //max elements in array
int tablefill(int *a, int max);
int tablediff (const int *a, const int *b, int sza, int szb);
void tableprn (const int *a, int sza);
int main (void) {
int a[MAX];
int b[MAX];
int idx, sza, szb;
sza = tablefill (a, MAX);
szb = tablefill (b, MAX);
tableprn (a, sza);
tableprn (b, szb);
if ((idx = tablediff (a, b, sza, szb)) == -1)
printf ("\n the arrays are the same.\n\n");
else
printf ("\n the arrays differ at index '%d'\n\n", idx);
return 0;
}
/* read values from stdin into array up to 'max' values */
int tablefill (int *a, int max)
{
int idx = 0, tmp;
while (idx < max && scanf (" %d", &tmp) == 1)
a[idx++] = tmp;
return idx;
}
/* check if array 'a' and 'b' are the same, else return index
* of first difference, otherwise return -1 for equal arrays.
*/
int tablediff (const int *a, const int *b, int sza, int szb)
{
int i, lim = sza < szb ? sza : szb;
for (i = 0; i < lim; i++)
if (a[i] != b[i])
return i;
if (sza != szb)
return lim;
return -1;
}
/* print all elements in array. */
void tableprn (const int *a, int sz)
{
int i; //varriable to print
for (i = 0; i < sz; i++)
printf (" %d", a[i]);
printf ("\n");
}
Example Equal
$ /bin/arraycmp <../dat/20intsame.txt
8572 -2213 6434 16330 3034 12346 4855 16985 11250 1495
8572 -2213 6434 16330 3034 12346 4855 16985 11250 1495
the arrays are the same.
Example Differ
$ ./bin/arraycmp <../dat/20intdif.txt
8572 -2213 6434 16330 3034 12346 4855 16985 11250 1495
8572 -2213 6434 16330 3034 12346 4855 16985 11250 1494
the arrays differ at index '9'
Providing Prompts for Input
When taking user input, it is a good idea to proving meaningful prompts as well so the user isn't left looking at a blinking cursor wondering if the program has hung, or what is going on. So in addition to the logic above, you would want to add simple prompting that explains what the program needs and how to provide the input. Something simple will do:
printf ("\nenter a max of 10 integers below 'ctrl+d` to end.\n");
sza = tablefill (a, MAX);
printf ("enter a max of 10 integers below 'ctrl+d` to end.\n");
szb = tablefill (b, MAX);
printf ("\nthe arrays entered are:\n\n");
tableprn (a, sza);
tableprn (b, szb);
(note: to generate a manual EOF on windoze, the key combination is ctrl+z)
So for entering less than 10 integers for each array you could do something like:
$ ./bin/arraycmp
enter a max of 10 integers below 'ctrl+d` to end.
10 12 14 16 17
enter a max of 10 integers below 'ctrl+d` to end.
10 12 14 15 17
the arrays entered are:
10 12 14 16 17
10 12 14 15 17
the arrays differ at index '3'
Look over the example and let me know if you have any additional questions.