1

I have a program in Javascript that finds the max value of an array but now I want to translate directly into C. See below of Javascript and C code:

Javascript (works):

var tail = function(arr, pos, max) { //max and pos starts at 0 when called
    if (pos === arr.length - 1) {
        return arr[pos] > arr[max] ? arr[pos] : arr[max];
    }
    max = arr[pos] > arr[max] ? pos : max;
    return tail(arr, pos += 1, max);
};

C (need to be translated directly from Javascript):

int main(int arr[], int pos, int max) {
    if (pos == arr.length - 1) {
        return arr[pos] > arr[max] ? arr[pos] : arr[max];
    } else {
        max = arr[pos] > arr[max] ? pos : max;
        return (int arr[], int pos += 1, int max);
    }
}

What am I doing wrong in the C code?

user1585646
  • 421
  • 1
  • 4
  • 16
  • 6
    There is no such thing as .length for array in C. The length must be provided. And you need to declare a new function. – nhahtdh Dec 04 '12 at 05:58
  • Anyway, before you do any translation, make sure you know both the languages well enough to take care of all the side effect... It seems that you don't know much about C - so please get some book or tutorial about C first. – nhahtdh Dec 04 '12 at 06:00
  • @nhahtdh how would the new function look? – user1585646 Dec 04 '12 at 06:01
  • 3
    wow, this is the first time I see 'find maximum value in array' programmed using recursion – Andrey Sidorov Dec 04 '12 at 06:02
  • 1
    Writing a tail-recursive function in C is not recommended. The C stack is not guaranteed to be that large and there is no tail-call optimiser, so this is a waste of stack space that will blow up if your array gets long. – apmasell Dec 04 '12 at 06:03
  • Why don't you use a loop instead of recursion (both languages)? – Bergi Dec 04 '12 at 06:03
  • JavaScript version: `var max = Math.max.apply(Math, arr);` – Nathan Wall Dec 04 '12 at 06:04
  • @apmasell but thats what i'm trying to do.. – user1585646 Dec 04 '12 at 06:09
  • 2
    @apmasell Many modern compilers including gcc and clang support tail call optimization. – fuz Dec 04 '12 at 06:12
  • @FUZxxl: the C standard does not require tail-call optimisation. I would not write C code that assumes having it. Moreover, GCC doesn't do it all the time: http://stackoverflow.com/questions/490324/how-do-i-check-if-gcc-is-performing-tail-recursion-optimization – apmasell Dec 04 '12 at 14:33
  • @user1585646: Why are you trying to do it with a tail-call? Translating line for-line between any two languages is generally a bad idea. Programming languages, like human languages, come with idioms and patterns that vary. Tail-calls are very normal in Javascript and functional languages, but very awkward in C. You have to understand the code in the source language and write something equivalent in your target language, but not necessarily identical since it probably “won't make sense” or “won't be the normal way to do it”. – apmasell Dec 04 '12 at 14:38

3 Answers3

2

first of all, the code to find maximum element in array don't need to use recursion (you can, but it does not help to make code simpler here and worse, it requires you to have enough stack memory to put (array length)*(stack frame size).

Linear search example without recursion:

#include <limits.h>

int max_element(int arr[], int len) {
    int max = INT_MIN;
    for (int i=0; i < len; ++i)
        if (arr[i] > max)
            max = arr(i);
    return max;
}
Andrey Sidorov
  • 24,905
  • 4
  • 62
  • 75
  • You can't use `sizeof(arr)` on a formal argument and expect to get the array length. It will always be the size of a pointer. – Ted Hopp Dec 04 '12 at 06:25
1

You cannot know array's length in C.

main() function has a special meaning in C, program's entry point.

recursive syntax is also wrong.

Chul-Woong Yang
  • 1,223
  • 10
  • 17
1

This should work:

int tail(int *arr, int pos, int max, int len) {
    if (pos == len - 1) {
        return arr[pos] > arr[max] ? arr[pos] : arr[max];
    }
    max = arr[pos] > arr[max] ? pos : max;
    return tail(arr, pos + 1, max, len);
}

Just be aware that while this is a more-or-less faithful translation of the JavaScript, it is pretty awful code. Unless the compiler recognizes the tail recursion, this has the potential to overflow the call stack, especially for large arrays. It would be much better to iterate through the array. Here's a solution that arbitrarily returns 0 for an empty array:

int max(int *arr, int len) {
    int max = 0, i;
    if (len > 0) {
        max = arr[0];
        for (i = 1; i < len; i++) {
             if (arr[i] > max) max = arr[i];
        }
    }
    return max;
}
Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
  • @user1585646 - Why not? Doesn't compile? Gets the wrong answer? (If the latter, example please, and info on how you are calling it.) – Ted Hopp Dec 04 '12 at 06:22
  • @user1585646 - Oops. Needed to add argument types. Should be fixed now. – Ted Hopp Dec 04 '12 at 06:26
  • Undefined symbols for architecture x86_64: "_main", referenced from: start in crt1.10.6.o ld: symbol(s) not found for architecture x86_64 collect2: ld returned 1 exit status – user1585646 Dec 04 '12 at 07:01
  • @user1585646 - well, yes, you need a `main()`. I assumed this was supposed to be a function that was called from somewhere else. You can't pass all those arguments to `main()`. – Ted Hopp Dec 04 '12 at 15:48