LeetCode 665: Non-decreasing Array (C)
The code mutates an array. It is not good.
The code does too much. You may return false as soon as max_changes reaches 2 (no need to examine the rest).
More functions please. It is very hard to follow the complicated decision making. Consider
int find_first_violation(int * nums, int size)
{
    int i = 0;
    for (; i &lt; size; i++) {
        if (nums[i] &lt; nums[i-1]) {
            break;
        }
    }
    return i;
}

Then the business logic would be:
    int violation = find_first_violation(nums, size);

    if (violation == size) {
        // array is already non-decreasing
        return true;
    }
    if (violation == size - 1) {
        // easily fixable: increase nums[size - 1]
        return true;
    }

    // Now fix the violation
    // violation == 1 is fixable by decreasing nums[0]. No action needed.
    // Otherwise, we only care about the case where nums[violation] is too
    // small - less than two preceding numbers. It is only fixable by
    // increasing it, effectively setting it equal to nums[violation - 1].

    if ((violation &gt; 1) &amp;&amp; (nums[violation] &lt; nums[violation - 2])) {
        nums[violation] = nums[violation - 1];
    }

    // Finally, the core argument to have more functions: there
    // must be no more violations.

    return find_first_violation(nums + violation, size - violation) == size - violation;

Of course the first two conditions can be combined into violation &gt;= size - 1. Of course increasing of nums[violation] can be virtual, without mutating the array (if nums[violation - 1] &gt; nums[violation + 1] we may immediately return false;).