Having trouble in how to modify a single specific call to function - c

I've been having some problems in understanding what I exactly have to do here:
1 #include <stdio.h>
2 define N 10
3
4 int f(int *, int );
5
6 int main (void) {
7 int a[] = {11, 4, 3, 41, 15, 12, 4, 2, 8, 33};
8 printf ("%d\n", f(a, N) );
9 }
10
11 int f(int *a, int n) {
12 int i, m;
13 m = a[0];
14 for (i = 1; i < n; i++)
15 if (a[i] > m) m = a[i];
16 return m;
17 }
It's asking me to modify ONLY line 8 (can't modify anything else) so that the function f will be executed only in the second part of the array (as in, from 12 to 33).
I've tried to come up with a solution for a long time but to no avail.
Help would be much appreciated.
Thanks in advance!

Take into account that an array passed to a function as an argument is implicitly converted to pointer to its first element.
In general you can pass to your function a pointer pointing to any element of the array. To do so you can use the pointer arithmetic.
The element with the value 12 is the sixth element of the array that is it can be obtained like a[5]. So you can write either like
printf ("%d\n", f( &a[5], N - 5) );
or like
printf ("%d\n", f( a + 5, N - 5) );
Or if you need to do the task for a half of the array then you can write
printf ("%d\n", f( &a[N / 2], N - N /2) );
or
printf ("%d\n", f( a + N / 2, N - N / 2) );

Replace the line 8 by
printf ("%d\n", f(a+5, N/2) );
Reason:
6th element inside the array is stored at index 5 i.e. a[5]
and a[5]=*(a+5)
So we need to pass a+5 without de-referencing it. And size is 10 so N/2 would mean 5.
Inside the function you actually start from 6th element and iterate through next 5 elements as n is 5.

Related

Operator and Pointer precedence

Below is the problem I found on the internet.
int main()
{
int a[4] = { 10, 21, 32, 43};
int *p = a + 3;
++*--p;
++*p--;
p[2] += p[1];
for (int i = 0; i < 4; ++i)
printf("%d - %d\t", a[i]);
return 0;
}
//What will be the output?
answer : 10 21 34 77
I understood a lot of things, but the only thing I'm stuck on:
What is the difference between (++*--p) and (++*p--) ?
Shouldn't these two give the same result? Because (*p--) and (*--p) give the same result in the compiler. The compiler I use is Code::Blocks
Because (*p--) and (*--p) give the same result in the compiler.
No, they do not. *p-- decrements p but applies * to the value of p before the decrement. *--p applies * to the value of p after the decrement.
What is the difference between (++*--p) and (++*p--) ?
++*--p decrements p and increments the object it points to after the decrement.
++*p-- decrements p but increments the object it points to before the decrement.
What is the difference between (++*--p) and (++*p--) ?
The difference is that --p decrements p and resolves to the new value of p, whereas p-- decrements p and resolves to the old value of p.
++* works identically on both - performing indirection on p, incrementing the value p points to, and resolving to this new value.
#include <stdio.h>
int main(void)
{
int a = 10;
int b = 10;
/* This prints 9, and `a` is now 9 */
printf("%d\n", --a);
/* This prints 10, and `b` is now 9 */
printf("%d\n", b--);
/* This prints 9 and 9 */
printf("%d %d\n", a, b);
}
Shouldn't these two give the same result? Because (*p--) and (*--p) give the same result in the compiler.
The order here matters, using (*--p) before (*p--) would resolve to the same element twice. Using (*p--) before (*--p) resolves to different elements.
#include <stdio.h>
int main(void)
{
int a[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
int *p = a + 4;
/* 4 then 4 */
printf("%d ", *--p);
printf("%d\n", *p--);
p = a + 4;
/* 5 then 3 */
printf("%d ", *p--);
printf("%d\n", *--p);
}

How to find a missing value in an array? [duplicate]

This question already has answers here:
Why sizeof(param_array) is the size of pointer?
(8 answers)
Closed 9 months ago.
I am trying to find the smallest missing element of an array using function check, which has two arguments (n and array A). I can't understand why my function check is always returning one and the while loop is never closing.
#include <stdio.h>
bool check(int n, int A[])
{
for (int i = 0; i < sizeof(A); i++)
{
if(A[i] == n)
{
return 1;
}
}
return 0;
}
int main()
{
int A[] = {1, 3, 6, 4, 1, 2};
int n = 1;
while (check(n, A) == 1)
{
n++;
}
printf("%d is missing",n);
}
The compiler adjusts a parameter having an array type to pointer to the array element type.
So this function declaration
bool check(int n, int A[])
is equivalent to
bool check(int n, int *A );
And within the function the expression sizeof(A) is equivalent to the expression sizeof( int * ) and is equal to either 4 or 8 depending on the used system.
Thus this for loop
for (int i = 0; i < sizeof(A); i++)
invokes undefined behavior.
I know but still that's not why the while loop is never stopping.
Answering your above comment it seems that in the used system sizeof( int * ) is equal to 8 and the variable n is placed in memory after the array A as they defined in main
int A[] = {1, 3, 6, 4, 1, 2};
int n = 1;
As a result you get the infinite wile loop because in the for loop within the function the memory occupied by the variable n is checked and n is always equal to itself.
Thus the function always returns 1.
That is in the for loop the array is traversed as it has 8 elements like
int A[] = {1, 3, 6, 4, 1, 2, n, some_indeterminate_value };

K&R Quicksort issue

I seem to be having a problem understanding where the issue is in the qsort implementation by K&R (C Programming Language second edition).
void qsort_1(int v[], int left, int right)
{
int i, last;
void swap(int v[], int i, int j);
if (left >= right)
return;
swap(v, left, (left + right)/2);
last = left;
for (i = left + 1; i <= right; i++)
if (v[i] < v[left])
swap(v, ++last, i);
swap(v, left, last);
qsort_1(v, left, last-1);
qsort_1(v, last+1, right);
}
This is their version, I only renamed it to qsort_1 so that I could use the built in one at the same time.
int arr_len = 9;
int main() {
int a[] = { 5, 5, 4, 6, 3, 7, 8, 13, 17 };
int b[] = { 5, 5, 4, 6, 3, 7, 8, 13, 17 };
print_a(a, arr_len); // print first array
print_a(b, arr_len); // print second array
putchar('\n'); // space
qsort(b, arr_len, sizeof(int), cmpfunc); // sort second array with standard qsort
qsort_1(a, 0, arr_len); // sort first array with K&R qsort
print_a(a, arr_len); // print first array
print_a(b, arr_len); // print second array
return 0;
}
print_a is a mini function for displaying an array, just one for loop.
qsort is the official standard implementation.
The output I get is:
gcc -O2 -lm -o qsort qsort.c
5 5 4 6 3 7 8 13 17
5 5 4 6 3 7 8 13 17
0 3 4 5 5 6 7 8 13
3 4 5 5 6 7 8 13 17
There seems to be a leading 0 and the last element is removed in the K&R qsort everytime. ...Help
void print_a(int a[], int len) {
for (int i = 0; i < len; i++) {
printf("%d ", a[i]);
}
printf("\n");
}
int cmpfunc (const void * a, const void * b) {
return ( *(int*)a - *(int*)b );
}
If needed, here are the cmpfunc and print_a.
Tried googling the problem but no one seemed to have the same issue.
EDIT:
The code changed in the main function:
int main() {
int a[] = { 5 , 5 ,4 ,6 ,3 ,7 ,8, 13, 17 };
int b[] = { 5 , 5 ,4 ,6 ,3 ,7 ,8, 13, 17 };
print_a(a, arr_len);
print_a(b, arr_len);
putchar('\n');
qsort(b, arr_len, sizeof(int), cmpfunc);
qsort_1(a, 0, **arr_len - 1**);
print_a(a, arr_len);
print_a(b, arr_len);
return 0;
}
When in doubt, look at the code you wrote.
We can assume for a moment that K&R knew what they were doing.
We can further assume that the authors of qsort in the standard library knew what they were doing as well.
Therefore, the first places we should look at what you authored. So what did you really author. The print function, the qsort comparator, and basically everything in main. A quick review reveals:
print_a is certainly ok, provided the base address and length are valid (and they are in this usage case), so that's out.
The qsort comparator seems correct, since (a) it works, and (b) it has nothing to do with questionable output from a totally unrelated function, qsort_1. So that's out.
That leaves only main. Within that function we have:
int main()
{
int a[] = { 5, 5, 4, 6, 3, 7, 8, 13, 17 };
int b[] = { 5, 5, 4, 6, 3, 7, 8, 13, 17 };
print_a(a, arr_len); // print first array
print_a(b, arr_len); // print second array
putchar('\n'); // space
qsort(b, arr_len, sizeof(int), cmpfunc); // sort second array with standard qsort
qsort_1(a, 0, arr_len); // sort first array with K&R qsort
print_a(a, arr_len); // print first array
print_a(b, arr_len); // print second array
return 0;
}
From this:
The array declarations are certainly ok.
The print_a calls check out ok (base address and length are valid).
The call to qsort is unrelated, and obviously ok.
That leave only one line of code in this entire program that could be the culprit:
qsort_1(a, 0, arr_len); // sort first array with K&R qsort
Checking the algorithm, the K&R function expects:
The array base address (ok)
The first index in the partition to sort, in this case 0. (ok)
The last index in the partition to sort. Um...
That's the problem. arr_len is not the last index. It is the length of the sequence. Since arrays in C are 0-index based, the last index is therefore arr_len-1, not arr_len.
Fix that:
qsort_1(a, 0, arr_len-1);
And the code will work as-expected.

I have to reverse the array [1,2,3,4,5,6,7] and i am stuck

#include <stdio.h>
int reverse(int *prr, int i)
{
for (i = 6; i; i--)
{
printf("%d is reverse \n", *prr + i);
}
}
int main()
{
int arrr[] = {1, 2, 3, 4, 5, 6, 7};
int *ptr = arrr;
reverse(ptr, 6);
return 0;
}
The output I am getting is
7 is reverse
6 is reverse
5 is reverse
4 is reverse
3 is reverse
2 is reverse
but not 1!
The loop condition i is equivalent to i != 0 (and for your specific use-case i > 0).
That is, the loop will end when the i reaches 0, so that index will not be printed.
To be able to print the last element, you need to include it in the loop with a condition like i >= 0.
While the off-by-1 question has been answered already, a slightly more idiomatic C way to write it would be to pass the array count as an argument (instead of count-1), and use pointer arithmetic (instead of indexing).
void reverse(int *prr, int i)
{
for (prr += i; i--; )
{ printf("%d is reverse \n", *--prr); }
}
int main()
{
int arrr[] = {1, 2, 3, 4, 5, 6, 7};
reverse(arrr, sizeof(arrr) / sizeof(arrr[0]));
return 0;
}
You have a couple of different ways to write the function. Though as #dxiv pointed out in your comments you want *(prr + i) instead of *prr + i (which by happy mistake just happened to output the same numbers corresponding the elements 1 - 7)
When you want to access a specific element from an array, you options are *(ptr + index) which is equivalent to ptr[index] (or for that matter index[ptr]).
Whenever you need to loop a certain number of times, you can simply decrement the counter, e.g.
#include <stdio.h>
void reverse (int *prr, size_t nelem)
{
while (nelem--)
printf ("%d is reverse\n", *(prr + nelem));
}
int main()
{
int arrr[] = {1, 2, 3, 4, 5, 6, 7};
reverse (arrr, sizeof arrr/sizeof *arrr);
}
Another approach for reversal is a recursive function, e.g.
void reverse (int *prr, size_t nelem)
{
if (nelem) {
printf ("%d is reverse\n", *(prr + nelem - 1));
reverse (prr, nelem - 1);
}
}
or even
void reverse (int *prr, size_t nelem)
{
printf ("%d is reverse\n", *(prr + --nelem));
if (nelem)
reverse (prr, nelem);
}
Example Use/Output
The output of all are equivalent, e.g.:
$ ./bin/reverse_arr_fn
7 is reverse
6 is reverse
5 is reverse
4 is reverse
3 is reverse
2 is reverse
1 is reverse

Why array values are different from assigned values C program

I wrote a small code to that takes an array of 10 values, passes the array to a function which doubles each value. The array prints expected values (double) within the function. Back in the main function, the output printed has garbage values for index 1, 2 and 3 in the for loop meant to print all values. Why are these values altered? The address is the same in both main and called functions.
StructA doubleArray(int* alist, int b) {
StructA doubled;
int temp[b];
for(int i=0; i < b; i++){
temp[i] = 2 * alist[i];
}
doubled.a = temp;
doubled.b = b;
return doubled;
}
int main() {
int arange[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int len = 10;
StructA hasDoubledValues = doubleArray(arange, len);
printf("\nvalues in main :");
for(int k = 0; k < hasDoubledValues.b; k++){
printf(" %d \n", hasDoubledValues.a[k]);
}
return 0;
}
its printing values as : 0 0 -14334592 32507 8 10 12 14 16 18
I expected the values to be : 0 2 4 6 8 10 12 14 16 18
int temp[b]; is local to the function.
Once you return from the function, lifetime of that memory ceases and accessing it would yield undefined behaviour.

Resources