Finding the maximum of an array recursively - c

I am learning recursion. As an exercise I am trying to find the maximum of an array recursively.
int recursive (int *arr, int n, int largest) {
if(n==0)
return largest;
else {
if (*(arr+n)>largest) {
largest = *(arr+n);
recursive(arr, n-1, largest);
}
}
}
int main() {
int length = n-1;
int largest = v[0];
int z = recursive(arr, length, largest);
printf("\n%d", z);
}
I followed your suggestions, using pointers instead of arrays, and probably the program looks way better. But still it is not doing it's not showing the maximum correctly. I think the logic is correct.

First thing pay attention to compiler warnings, your recursive function doesn't return value when you enter the else part.
Now the second thing is please don't use things like *(arr+n) which is hard to read instead use arr[n], also while just a preference when using arrays as function arguments use int arr[] to call the function instead of int *arr (in the first version it's clear you should pass an array).
Third thing is to name your things instead of int recursive describe what the function is doing for example int maxElemRecursive
So your recursive function should be something like
int maxElemRecursive(int arr[],int n,int largest)
{
if(n==0) return largest;
if(arr[n] > largest) // No need for else because return largest; would've returned value;
{
largest = arr[n];
}
return maxElemRecursive(arr,n-1,largest); // You have to return the value of the function.
// You still pass the array with just arr.
}

In C usually you can't declare an array whose size is unknown at compile-time, hence int v[n] is dangerous code.
Depending on your compiler and the compiler's settings this could be a compile error or it could be a bug.
For such problems you need to learn about pointers and dynamic memory allocation.
Side-note: After C99 there are stuff like Variable Length Arrays but the rules are a little advanced.
Also to pass an array to a function you give the array a pointer as an argument:
int z = recursion(v, n, v[0]);
instead of:
int z = recursion(v[n], n, v[0]);

Related

Function pointers and callbacks in c/c++

I was trying to remind how pointers worked in c and c++ and I found this very interesting video (Pointers in C/C++). In minute 3:14:00, he begins to talk about pointer functions and callbacks, and I ended a bit confused about the real application of them.
The example case he provides consists of a sorting algorithm that takes a function pointer as argument, which defines the comparison "rule" to follow (order from geater to smaller, order from smaller to greater, from greater to smaller given the absolute values...). He eventually ends with something like this:
#include<stdio.h>
int compare(int a, int b){
if(a > b) return -1;
return 1;
}
void MyBubbleSort(int A[], int n, int (*compare)(int,int)){
int i,j,temp;
for(i=0; i<n; i++){
for(j=0; j<n-1; j++){
if(compare(A[j], A[j+1]) > 0{
temp = A[j];
A[j] = A[j+1];
A[j+1] = temp;
}
}
}
}
int main(){
int i, A[] = {3,2,1,5,6,4};
MyBubbleSort(A,6,compare);
for(i=0; i<6; i++) printf("%d ",A[i]);
}
When he wants to change the comparison rule, he changes the compare(int, int) content and that's all. My question is, why would he do that, instead of just having a separate function called compare(int, int) that just does the same as the one showed in the code snippet, and just call that function from within MyBubbleSort(int[], int). Wouldn't it just have the same behaviour? What are the benefits then? Are there any other interesting use cases?
Thank you very much for answers!
If I understand your question correctly, the main point is something that he mentions in the narration but does not include in the sample code: you could have several different comparison functions in your program, and use them at different times as appropriate, while still having just one MyBubbleSort function.
An example might look like:
int compare_increasing(int a, int b){
if(a > b) return -1;
return 1;
}
int compare_decreasing(int a, int b){
if(a < b) return -1;
return 1;
}
void MyBubbleSort(int A[], int n, int (*compare)(int,int));
}
int main(){
// ...
// sort in increasing order
MyBubbleSort(A,6,compare_increasing);
// sort in decreasing order
MyBubbleSort(A,6,compare_decreasing);
}
Calling a function by a pointer in this case makes the sorting function universal.
If you hardcode the comparison in that function it will work only for that condition.
C does not have lambda expressions and anonymous functions so the compare function has to be written separately and the pointer passed.

Error defining an array

I want to introduce as stated in the title, a binary search function to my program. But keep getting two errors which I have no clue how resolve.
This is the compiling-error I get for my code:
: expected expression before '{' token
array[size]={1,3,6,8,12,13,16};
^
upg10.8.c: In function 'binarySearch':
upg10.8.c:55:7: warning: control reaches end of non-void function [-Wreturn-
type]
}
^
Any idea to what is causing the problem in both cases?
You can find the code below:
#include <stdio.h>
#include <stdlib.h>
int binarySearch(int n, int array[], int search);
int main(void){
int search, size=7, array[size], middle;
array[size]={1,3,6,8,12,13,16};
printf("input search number:\n");
scanf("%d", &search);
middle = binarySearch(size, array, search);
if(middle ==-1){
printf("There is no index corresponding to that search number");
}
else{
printf("Index %d for Search%d", middle, search);
}
return 0;
}
int binarySearch(int n, int array[], int search){
int first =0;
int last = n-1;
int middle= (first+last)/2;
while(first<=last){
if(array[middle]<search)
first= middle +1;
else if(array[middle]==search){
return search;
}
else
last = middle -1;
middle = (first +last )/2;
return middle;
break;
}
if(array[first]>array[last])
return -1;
}
Remove the array[size]={1,3,6,8,12,13,16};. You cant initialize value to array after declaration. But only on the time of deceleration. The correct code is
int array[]={1,3,6,8,12,13,16};
Also declare size as macro constant. I think its better. It will look like
#define size 7
Everything else look fine!!
int search, size=7, array[size], middle;
Here you've defined the array object array. Note that the size is not a constant, so this is a VLA (variable-length array). Not all compilers support VLAs, and you don't need one here.
array[size]={1,3,6,8,12,13,16};
This is several kinds of wrong.
array[size] would be element 7 of array -- but array only has elements 0 through 6.
You obviously mean to assign the 7 values {1,3,6,8,12,13,16} to the 7 elements of array, but you can't do it this way. In fact, array objects can be initialized, but they can't be assigned to (for complicated historical reasons).
{1,3,6,8,12,13,16} is not an expression, so it can't appear on the right hand side of an assignment, regardless of what's on the left. It is a valid initializer.
Drop the definition of size and change the declaration of array to this:
int array[] = {1,3,6,8,12,13,16};
Since you've initialized array with 7 elements, you don't have to tell the compiler how many elements it has; the size is determined for you automatically. (That's one of the few things C will helpfully do for you.)
Now you could define
const int size = 7;
but then you'd have to carefully update the initializers for array and size together, and make sure they're consistent. Instead, you can compute the size:
const int size = sizeof array / sizeof array[0];

formal parameters and actual parameters in c

I just started learning functions and passing the parameters. so i am kind of new to this. Here, in the following programming, i am changing the values of a[] which is a formal parameter. even though, the sort function is not returning anything. how are the elements in numberArray[] are getting sorted even though the sort function just dealing with the formal parameters?
#include<stdio.h>
void sort(int[],int);
int main(void)
{
int n;
printf("enter the number of elements : ");
scanf("%d",&n);
int numberArray[n];
printf("enter %d numbers :\n",n);
for(int i=0;i<n;i++)
scanf("%d",&numberArray[i]);
sort(numberArray,n);
printf("sorted list of numbers are :\n");
for(int i=0;i<n;i++)
printf("%d\n",numberArray[i]);
return 0;
}
void sort(int a[],int n)
{
int i,j,temp;
for(i=0;i<n-1;i++)
{
for(j=i+1;j<n;j++)
{
if(a[i]>a[j])
{
temp=a[j];
a[j]=a[i];
a[i]=temp;
}
}
}
}
I would like to compare the above program with a simple program as follows.
#include<stdio.h>
void nothing(int);
int main(void)
{
int a;
printf("enter the value : ");
scanf("%d",&a);
nothing(a);
printf(" a = %d",a);
return 0;
}
void nothing(int b)
{
b=b+2;
}
In this program, the value of a is not changing. Why?
In C array parameters to functions are a fiction. Arrays don't get passed to functions; the parameter is treated as a pointer.
So in your example a is really an int*.
Personally, I think that function parameters declared as arrays is almost always a bad idea, since it doesn't model what is really being passed to the function. Until you understand what is really happening, it can cause confusion of the sort you ran into. It also commonly causes problems with people who try to obtain he size of the array passed to a function using the sizeof operator - that doesn't work since sizeof will return the size of a pointer type, not the actual array type.
The one situation where I think array formal arguments might make sense is with multi-dimension arrays, where the pointer arithmetic can be helpful.
Note that C99 introduced variable length arrays (VLAs) which can change much of this. VLAs are different animals, but because support for them came rather late (even after C99 was standardized, it took a while for may implementations to support them properly). This answer doesn't necessarily apply to passing VLAs as arguments to functions.
C passes by value ie
void nothing(int b) {
b=b+2;
}
is getting a copy of the integer. If you want to see the int change you need to pass it's address ie
void nothing(int *b) {
*b = *b + 2;
}
You pass the address as following
nothing(&a);
In the program you reference this function...
void sort(int a[],int n)
is taking a pointer to an array of integers as it's first argument so any change to it in the function changes the actual memory it points to

Passing array to function, to multiply every value of the array by 10

This program is to multiply every value of array by 10 using a function. I am getting a lot of errors.
Can I take size in for loop?
#include<stdio.h>
mult(int arr[])
{
int i;
for(i=0;i<size;i++)
{
arr*=10;
}
return arr;
}
int main()
{
int j[];
printf("enter the all ten values to multiply by 10");
for(j=0;j<size;j++)
scanf("%d");
j[] = mult(j);
printf("%d",&j);
return 0;
}
int j[]; You're creating an array wrongly (in this context). You have to specify its size. Eg.: int j[256];
for(j=0;j<size;j++) scanf("%d"); What's size? how can you increment an array?? You're using scanf wrongly. You should do for(int s=0;s<size;s++) scanf("%d",&j[s]);.
j[] = mult(j); is wrong again. You should create another array and copy values there.
printf("%d",&j); you don't need & here, remove it. You'd better use "%d\n" to print each number on its own line.
mult(int arr[]) function declared wrongly. You must specify a type your function returns. You may need to use int *mult(...) instead and return &arr[0];
arr*=10; what're you trying to achieve with this? Completely wrong, you're multiplying the address here.
Read the docs, please! Your code doesn't make any sense, please learn C first, then try to code.
Moreover, you'll need pointers here, pay attention to them. I'd advise you to write Hello World program first to just understand the basics. Mr. Kernighan and Mr. Ritchie will help you too.
Note: I may have missed some mistakes here as there are too many of them. Please correct me if so.
Here is a complete code learn the differences and correct your code:
#include<stdio.h>
void mult(int *arr,int size)
{
int i;
for(i=0;i<size;i++)
arr[i]*=10;
}
int main()
{
int size=10;
int j[size],i;
printf("enter the all ten values to multiply by 10\n");
for(i=0;i<size;i++)
scanf("%d",j+i);
mult(j,size);
for(i=0;i<size;i++)
printf("%d ",j[i]);
printf("\n");
return 0;
}
You must tell mult() what is the size of the array, and the array you are passing will be modified in mult() so you don't need to return a value.
mult(j, size);
and your mult() function
void mult(int *arr, size_t size)
{
int i;
for(i=0;i<size;i++)
{
arr[i] *= 10;
}
}

Passing pointers to an array as arguments to a function

I am trying to implement INSERTION SORT here in C, which I think I've done successfully. However, I am having problems in passing arrays as arguments.
I want in place sorting, which means that the original array passed into the insertion_sort function should contain the elements in the sorted array itself.
#include<stdio.h>
int * insertion_sort(int *a,int length)
{
int j;
for(j=1;j<length;j++)
{
int i,key=a[j];
for(i=j-1;j>=0;j--)
{
if(a[i]<=key)
break;
a[i+1]=a[i];
}
a[i+1]=key;
}
return *a;
}
int main(void)
{
int a[]={10,12,7,6,9,8};
insertion_sort(a,6);
int i;
for(i=0; i<6; i++)
printf("%d\n", a[i]);
return 0;
}
EDIT
Nothing gets printed in the output screen.
Help me find the bug here. Thanks !!
1.You probably meant to use i in the inner loop:
Change:
for(i=j-1;j>=0;j--)
^^ ^^
to:
for(i=j-1;i>=0;i--)
2.You don't have to return anything as the original array gets modified (which is just as well since you ignore the returned value).
3.Array index starts from 0. Change outer loop to: for(j=0;j<length;j++)

Resources