I have been asked to write a function that prints the content of an array after the xth element (as in, x and forth, as x is a pointer inside the array). I am not allowed to use [] for anything other than initialization, and not allowed to create variables inside the function - I may only use what the function receives from the main, which is the length (int n), the array (int* arr) and element x (int* x).
My question is how can I print x and forth in the array using only pointers without an index from a loop?
Here is what I wrote:
void printAfterX(int* arr, int n, int* x)
{
if ((arr <= x) && (x < arr + n))
{
while(x < (arr + n))
{
printf("%8d", *(arr+x)); //I know you can't do this
x++;
}
}
}
For this:
int arr[] = { 0,5,6,7,8,4,3,6,1,2 };
int n=10;
int* x = (arr+3);
printAfterX(arr, n, x);
The output should be:
7 8 4 3 6 1 2
Edit: Thanks y'all for the help! Works just fine. :)
void printAfterX(int* arr, int n, int* x)
{
arr += n; // make arr to point past the last element of the array
for( ; x < arr; x++) // walk till the end of array
printf("%8d", *x); // print the current item
}
Example https://ideone.com/Ea3ceT
You want this:
#include <stdio.h>
#include <stdlib.h>
void printAfterX(int* arr, int n, int* x)
{
while(x < (arr + n))
{
printf("%d ", *x);
x++;
}
}
int main()
{
int arr[] = { 0,5,6,7,8,4,3,6,1,2 };
int n = 10;
int *x = (arr+3);
printAfterX(arr, n, x);
return 0;
}
Change the printf line for this:
printf("%8d", *x);
Related
I have this recursive function, and I try to pass the result in 's' variable.
However if I use *s=*s+v[i]; the function works.
But if I try to call sum(v,i+2,s+v[i],n); It doesn't work anymore.
Can someone tell me what is wrong?
Here is the code:
void sum(int v[], int i, int *s, int n)
{
if (i < n)
{
if (v[i] < 0)
{
//*s = *s + v[i];
//sum(v, i + 2, s, n);
sum(v, i + 2, s + v[i], n);
}
else
sum(v, i + 2, s, n);
}
}
int main()
{
int n = 7;
int v[] = { -5,-8,4,4,3,9,-5 };
int i = 0;
int s = 0;
sum(v, i, &s, n);
printf("SUM IS: %d", s);
return 0;
}
There is a major difference between to 2 ways.
The correct one:
*s = *s +v[i]; // increases the int object pointed to by s
sum(v, i + 2, s, n); // still pass the same pointer to sum
The wrong one:
sum(v, i+2, s+v[i], n);
Here, the pointer is increased instead of the pointed object. It is equivalent to:
s = s +v[i]; // s is not dereferenced here!
sum(v, i + 2, s, n); // pass an incorrect pointer to sum
Looks like you have multiple problems that need correction.
First of all, the inner if is not needed. It is unclear what you wanted to do with this. Handling negative numbers separately? If so, it is not needed since the + operator can also handle addition of negative numbers.
Secondly, the s + v[i] adds the value in your array to the pointer to sum, which is not what you want. You need to use the * operator to dereference s here so that the number is added to the sum that the pointer points to. Your own commented-out code does this correctly.
Thirdly, using sum(v, i + 2, s, n); skips alternate elements so to sum the whole array properly, you need to use i + 1 instead of i + 2.
The following code fixes these issues.
void sum(int v[], int i, int *s, int n)
{
if (i < n)
{
*s += v[i];
sum(v, i + 1, s, n);
}
}
int main()
{
int n = 7;
int v[] = { -5,-8,4,4,3,9,-5 };
int i = 0;
int s = 0;
sum(v, i, &s, n);
printf("SUM IS: %d", s);
return 0;
}
I need to write a function which gets an array, it's size and a pointer, I need to check if the pointer exists in the array and if so, print all the elements after it and i'm not allowed to create local variables or use [].
This is what i did to find whether the pointer exists or not.
void printAfterX(int* arr, int n, int* x)
{
if (x < (arr + n) && x >= arr)
{
}
}
Thank you.
I'll give you two hints:
(1) Function parameters are l-values.
(2) Eventually recursion.
You should try both, even if recusion is an overkill here.
since the pointer exists
for(x; x < (arr + n); x++){
printf("%i\n", *x);
}
should do the job
You can use the operator + for this situation who works exactly like [] on pointers at this situation.
At Pseudo it's look like that:
void printAfterX(int* arr, int n, int* x)
{
if arr < x < arr+n{
print array(x)
}
}
Assuming your main data type is int, and that you want to match the content pointed by the pointer (not the pointer itself), here's a working solution:
#include <stdio.h>
void printAfterX(int*, int, int*);
int main() {
int array[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int sizeOfArray = 10;
int *pointerX = &array[4];
printAfterX(array, sizeOfArray, pointerX);
return 0;
}
void printAfterX(int* arr, int n, int* x) {
// Iterates over given array
for (int i = 0; i < n; i++) {
// If contents match
if(*(arr + i) == *x) {
for(int j = i + 1; j < n; j++) {
// Print all elements after found element
// (not-inclusive, i.e. j = i + 1)
printf("%d ", *(arr + j));
}
break; // break outer loop, because job's done
}
}
printf("\n"); // Line feed at end of iteration
}
This should also work:
bool SearchForPointer(int* arr, int n, int* x)
{
if( 0 == n)
return false;
if( arr == x)
{
while( --n)
{
arr++;
::printf( "Pointer: 0x%08X; Value: %d;\r\n", (intptr_t)(arr), *(arr));
}
return true;
}
return SearchForPointer( ++arr, --n, x);
}
int main()
{
int arr[] = {1, 2, 3, 4, 5};
int* p = arr+2;
::printf( "Searching for: p = 0x%08X; value: %d\r\n", (intptr_t)p, *p);
SearchForPointer( arr, 5, p);
return 0;
}
So, what I'm trying to achieve here, is to use the C implementation of qsort in a 2d array, in witch I want only the rows to be sorted based on the its first element, for example:
int arr[3][2]={{65,1},
{45,2},
{66,3}}
I want the output to be:
int arr[3][2]={{45,2},
{65,1},
{66,3}}
Is there a way of doing this without implementing quicksort myself? If so, how?
EDIT
This is what my code looks like:
int f(int a, int b)
{
return a-b;
}
qsort(arr[0],3,sizeof(int),f);
You're not sorting integers, you're sorting "things" that happen to be a number of integers in size.
So, don't lie to qsort() about your element size:
#include <stdio.h>
#include <stdlib.h>
static int cmprow(const void *a, const void *b)
{
const int * const ia = a, * const ib = b;
return ia[0] < ib[0] ? -1 : ia[0] > ib[0];
}
int main(void) {
int arr[3][2]={{65,1},
{45,2},
{66,3}};
qsort(arr, sizeof arr / sizeof *arr, sizeof *arr, cmprow);
for (size_t i = 0; i < sizeof arr / sizeof *arr; ++i)
{
for (size_t j = 0; j < sizeof *arr / sizeof **arr; ++j)
printf("%d ", arr[i][j]);
putchar('\n');
}
return 0;
}
This prints:
45 2
65 1
66 3
Here is the problem:
qsort(arr[0],3,sizeof(int),f);
This function take size_t as the second argument. You have passed 3. Thats not the size, thats count of elements in the array arr. In a crude way, you need something like 3*sizeof(int). Or better sizeof(arr) / sizeof *arr.
So, change it to
qsort(arr, sizeof(arr) / sizeof *arr, sizeof(int), sizeof *arr, comparator);
With:
int comparator(const void *p, const void *q)
{
// Get the values at given addresses
int l = *(const int *)p;
int r = *(const int *)q;
// both odd, put the greater of two first.
if ((l&1) && (r&1))
return (r-l);
// both even, put the smaller of two first
if ( !(l&1) && !(r&1) )
return (l-r);
// l is even, put r first
if (!(l&1))
return 1;
// l is odd, put l first
return -1;
}
I am getting error on the line where I put "<<--" (line 9) sign. it didn't had any compiling error , but while giving input it says "Segmentation fault: 11". I don't know what went wrong.
input:
3 3
1 1 1
2 2 2
3 1 5
The code:
#include <stdio.h>
#include <stdlib.h>
int comp (const void * x, const void * y)
{
int *a = *(int **)x;
int *b = *(int **)y;
//getting error here
if (a[0] == b[0]) // <<-- here
{
if (a[2] == b[2])
{
return -(a[1] - b[1]);
}
else
{
return a[2] - b[2];
}
}
else
{
return a[0] - b[0];
}
}
int main()
{
int n;
long long d;
scanf("%d %lld", &n, &d);
int t[n][3];
for (int i = 0; i < n; i++)
{
scanf ("%d %d %d", &t[i][0], &t[i][1], &t[i][2]);
}
printf("%lu\n", sizeof(t[0]));
qsort(t, n, sizeof(t[0]), comp);
for (int i = 0; i < n; ++i)
{
printf("%d-%d-%d\n", t[i][0], t[i][1], t[i][2]);
}
}
Can anyone help me with this?
Your
int t[n][3];
array is actually an 1D array consisting of n 1D arrays of type int [3]. These int [3] objects is what you are trying to sort by your
qsort(t, n, sizeof(t[0]), comp)
call.
So, in order to properly compare these objects you have to interpret the parameters of your comparison callback as pointers to int [3] objects. Meanwhile, your current implementation of comp is written as if the parameters are pointing to int * objects, which is incorrect. int [3] and int * are two very different things.
This is how you can do it
int comp (const void * x, const void * y)
{
int (*a)[3] = x;
int (*b)[3] = y;
// And now compare the arrays by accessing them as `(*a)[1]`,
// `(*b)[2]` and so on
}
Alternatively, you can write the comp prologue code as
int comp (const void * x, const void * y)
{
const int *a = *(int (*)[3]) x;
const int *b = *(int (*)[3]) y;
// And now compare the arrays by accessing them as `a[1]`,
// `b[2]` and so on, i.e. keep the rest of your code unchanged
}
This assumes that the rest of your comparison logic is correct. Note though that comparing int values by subtracting them from each other is risky, since it can overflow.
This question already has answers here:
How do I determine the size of my array in C?
(24 answers)
Closed 7 years ago.
I have some C code to practice the quick sort. I want to use macro the get the length of the array. The macro works fine in the main() function. But when I use the macro inside the sort function, it does not return the length of array.
Please see the comments inside the code I left.
Also, I want to use struct to create the member function pointer called "sort" and "quick_sort". Any people who are good at c programming gives me some advise if there are some points that I can improve, not matter the syntax, the code format. I feel kind of weird about the sort and quick_sort functions format inside the struct. My purpose is use Array struct to call the functions.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NELEMS(a) (sizeof(a) / sizeof(a[0]))
typedef struct _Array Array;
struct _Array
{
void (*sort)(int* arr);
void (*quick_sort)(int* arr, int l, int r);
};
void sort(int* arr);
void sort(int* arr)
{
// Issues here.
// The len is 2 not 5.
// the macro returns the sizeof arr here is 8, not 20.
int len = NELEMS(arr);
if(len == 0){
return;
}
void quick_sort(int* arr, int l, int r);
quick_sort(arr, 0, len-1);
}
void quick_sort(int* arr, int l, int r)
{
int j;
if(l < r)
{
j = partition(arr, l, r);
quick_sort(arr, l, j - 1);
quick_sort(arr, j+1, r);
}
}
int partition( int* a, int l, int r) {
int pivot, i, j, t;
pivot = a[l];
i = l; j = r+1;
while( 1)
{
do ++i; while( a[i] <= pivot && i <= r );
do --j; while( a[j] > pivot );
if( i >= j ) break;
t = a[i]; a[i] = a[j]; a[j] = t;
}
t = a[l]; a[l] = a[j]; a[j] = t;
return j;
}
void print_array(int* array, int len){
int i;
for(i = 0; i < len; i++)
printf("%d, \n", array[i]);
}
int main(int argc, char const *argv[])
{
int nums[5] = {5, 1, 3, 2, 4};
// len is 20 / 4 = 5. It works fine.
int len = NELEMS(nums);
Array *array = malloc(sizeof(Array));
array->sort = sort;
array->quick_sort = quick_sort;
sort(nums);
print_array(nums, NELEMS(nums));
return 0;
}
The macro works in main because nums is an array, sizeof(nums) gets the size of the array.
However, when it's passed as function argument, it's automatically converted to a pointer. In sort(), sizeof(nums) only gets the size of the pointer.
You could fix it by passing the size of the array explicitly.