#include <stdlib.h>
int int_sorter( const void *first_arg, const void *second_arg )
{
int first = *(int*)first_arg;
int second = *(int*)second_arg;
if ( first < second )
{
return -1;
}
else if ( first == second )
{
return 0;
}
else
{
return 1;
}
}
int main()
{
int array[10];
int i;
/* fill array */
for ( i = 0; i < 10; ++i )
{
array[ i ] = 10 - i;
}
qsort( array, 10 , sizeof( int ), int_sorter );
for ( i = 0; i < 10; ++i )
{
printf ( "%d\n" ,array[ i ] );
}
}
I don't understand this line :
int first = *(int*)first_arg;
could anyone help me? explain it? thank you very much!!!
Is this a casting? explicit cast, from void* to int? but why we need ampersand outside ()?
You are first casting the void pointer to an int pointer:
(int*)first_arg
And then dereferencing the pointer: *(int*)first_arg to get the integer it points to. This is then assigned to an integer variable.
int first = *(int*)first_arg;
is the same as:
int* ptrToFirst = (int*)first_arg;
This is an explicit cast from const void* to int.
int first = *ptrToFirst;
Here the * is the dereferencing operator. This is pronounced 'star'.
This is an 'ampersand': '&'.
Why are we doing this? qsort() needs to have the callback determine the ordering. By passing the values indirectly as const void pointers, the arguments to the callback have fixed size even though the values could be any size. That is why the values need cast back in the callback.
Related
I'd like to increase each element in the array by one in another function than the main function. Then, I'd like to call this function and print in the main function.
#include <stdio.h>
int function(int array2[5]) {
int i;
while(i<4) {
array2[i]=array2[i]+1;
i++;
}
return array2[5];
}
int main() {
int array[5]={1,2,3,4,5};
int answer;
answer[5]=function(array[5]);
int j;
while(j<4) {
printf("%d \n",answer[j]);
j++;
}
return 0;
}
Some important things to know:
When you pass an array in C, you don't make a copy. It is the same array, so modifying the array that is passed in modifies the original.
The [] are operators and not part of the variable name.
The [] work differently in declaring a type than when used in an expression. array[5] gives you the 6th element in array, but int array[5] declares an array with 5 elements.
Accessing an element beyond the end of the allocated array has undefined behavior, but usually will crash.
If you declare a variable int answer it is not an array, and cannot become an array. It is just one int
If you want to make a copy of an array, you need to explicitly copy. There are standard libraries that might do it, but you should learn to copy each element, one by one, to the new array.
The return type int of the function does not make a sense.
int function(int array2[5]) {
And moreover you are trying to return the non-existent 6-th element of an array with only 5 elements.
return array2[5];
Within the function you are using uninitialized variable i
int function(int array2[5]) {
int i;
while(i<4) {
//...
that results in undefined behavior. Also the used magic number 4 does not make a sense at least because you are trying to pass to the function an array with 5 elements.
The function should be declared with a second parameter that specifiers the number of elements in the passed array. This function declaration
int function(int array2[5]);
does not mean that the passed to the function array has exactly 5 elements. The compiler will adjust the parameter declaration of the function to pointer to the array element type like
int function(int *array2);
In this statement in main
int answer;
answer[5]=function(array[5]);
you are using the subscript operator with an object of the scalar type int. So the compiler shall issue an error message.
Here is a demonstrative program that shows how the function can be defined.
#include <stdio.h>
void function( int a[], size_t n )
{
for ( ; n--; ++a )
{
++*a;
}
}
int main(void)
{
int a[] = { 1, 2, 3, 4, 5 };
const size_t N = sizeof( a ) / sizeof( *a );
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
function( a, N );
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
return 0;
}
The program output is
1 2 3 4 5
2 3 4 5 6
There you go. I suppose this is what you want:
#include <stdio.h>
// Since the array named parameters are scoped only within its function,
// they are apart from your array in the main.
void function(int array[], int len) {
int i = 0;
while(i<len) {
array[i]=array[i]+1;
i++;
}
}
// Or alternatively you can process the array using a pointer
void functionWithPointer(int *array, int len) {
int i = 0;
while(i<len) {
*(array+i) = *(array+i)+1;
i++;
}
}
int main() {
int array[]={1,2,3,4,5};
// int answer; // Not necessary
int length = sizeof(array) / sizeof(int); // !!!ATTENTION
function(array, length);
// The array values updated by 1
printf("Array values after 1st update\n");
for(int k=0; k<length; k++) {
printf("%d \n",array[k]);
}
functionWithPointer(array, length);
// The array values updated by 1 again
printf("Array values after 2nd update\n");
int j;
while(j<length) {
printf("%d \n",array[j]);
j++;
}
return 0;
}
Here is the output:
Array values after 1st update
2
3
4
5
6
Array values after 2nd update
3
4
5
6
7
I want to retrieve the index in the array where the value is stored. I know the value of the item at that point in the array. I'm thinking it's similar to the findIndex function in c#.
For example, array[2] = {4, 7, 8}. I know the value is 7, how do I get the value of the index, 1, if I know it is at array[1]?
For example you can define the corresponding function the following way
size_t FindIndex( const int a[], size_t size, int value )
{
size_t index = 0;
while ( index < size && a[index] != value ) ++index;
return ( index == size ? -1 : index );
}
Also instead of type size_t you can use type int.
But the better way is to use standard algorithm std::find or std::find_if declared in header <algorithm> provided that you use C++
For example
#include <algorithm>
#include <iterator>
int main()
{
int a[] = { 4, 7, 8 };
auto it = std::find( std::begin( a ), std::end( a ), 7 );
if ( it != std::end( a ) )
{
std::cout << "The index of the element with value 7 is "
<< std::distance( std::begin( a ), it )
<< std::endl;
}
}
The output is
The index of the element with value 7 is 1
Otherwise you have to write the function yourself as I showed abve.:)
If the array is sorted you can use standard C function bsearch declared in header <stdlib.h>
For example
#include <stdio.h>
#include <stdlib.h>
int cmp( const void *lhs, const void *rhs )
{
if ( *( const int * )lhs < *( const int * )rhs ) return -1;
else if ( *( const int * )rhs < *( const int * )lhs ) return 1;
else return 0;
}
int main()
{
int a[] = { 4, 7, 8 };
int x = 7;
int *p = ( int * )bsearch( &x, a, 3, sizeof( int ), cmp );
if ( p != NULL ) printf( "%d\n", p - a );
return 0;
}
First its important that the argument list contain size information for the array, i.e. passing a pointer to an array only does not provide enough information to know how many elements the array has. The argument decays into a pointer type with no size information to the function.
So given that, you could do something like this:
int findIndex(int *array, size_t size, int target)
{
int i=0;
while((i<size) && (array[i] != target)) i++;
return (i<size) ? (i) : (-1);
}
For small arrays this approach will be fine. For very large arrays, some sorting and a binary search would improve performance
Here's my version without a additional variable.
// Return index of element starting
// Return -1 if element is not present
int indexOf(const int elm, const int *ar, int ar_cnt)
{
// decreasing array count till it reaches negative
// arr_cnt - 1 to 0
while (ar_cnt--)
{
// Return array index if current element equals provided element
if (ar[ar_cnt] == elm)
return ar_cnt;
}
// Element not present
return -1; // Should never reaches this point
}
Hope the comments are self explanatory!
I want to make a function pointer array and be able to call them in a for-loop. How can I achieve this? I have tried:
void (**a) (int);
a[0] = &my_func1;
a[1] = &my_func2;
a[2] = &my_func3;
for ( i = 0; i < 3; i++){
a[0]();
(*a[0])(); // Neither does work
}
But I am missing some syntax I guess:
error: too few arguments to function ‘*(a + (long unsigned int)((long unsigned int)i * 8ul))’
The function you declare is expected to take an int as a parameter:
a[0](1);
Also note that you declare a pointer to pointer for the functions, but you don't allocate any memory for them (I assume this is only in the example) Otherwise it should probably be:
void (*a[3]) (int);
You are declaring that a is a pointer to a pointer to (or an array of pointers to) a function that takes an int as a parameter - so you need to pass an int when you call the functions, e.g. a[0](42);.
I guess the below code is what you need.
typedef void * func_pointer(int);
func_pointer fparr[10];
for(int i = 0; i<10; i++)
{
fparr[i](arg); //pass the integer argument here
}
1) Where have you allocated or defined array to store function addresses?
2) in loop you are always calling (*a[0])();,There should be loop counter
You forgot to give an argument to your function.
void (**a) (int); // here it takes an int argument
a[0] = &my_func1;
a[1] = &my_func2;
a[2] = &my_func3;
for ( i = 0; i < 3; i++){
a[0](); // here you do not give an argument
}
But be careful, you do not allocate memory to your a array, and it fails with a nice segmentation fault error.
void my_func1(int i) {
;
}
void my_func2(int i) {
;
}
void my_func3(int i) {
;
}
int main() {
void (**a) (int);
a = malloc(3*sizeof(void*)); // allocate array !
a[0] = &my_func1;
a[1] = &my_func2;
a[2] = &my_func3;
for (int i = 0; i < 3; i++){
a[i](1); // respect your own function signature
}
free(a); // it's always a good habit to free the memory you take
return 0;
}
You can typedef void (*pfun)(int); and then pfun a[3]; is the array you want.
The following code may work for you:
typedef void (*pfun)(int);
int main() {
pfun a[3];
a[0] = myfunc1; // or &myfunc1 whatever you like
a[1] = myfunc2;
a[2] = myfunc3;
}
You can define your function-array with the needed size and initialize it with your functions like:
void my_func1(int x){}
void my_func2(int x){}
void my_func3(int x){}
void (*a[])(int)={my_func1,my_func2,my_func3};
int i;
for(i=0;i<sizeof a/sizeof*a;++i)
a[i](i);
The address-operator '&' before any function-name is redundant.
I'm getting gcc errors when I compile my code. The errors are about "passing argument 1 of ‘print_path’ makes pointer from integer without a cast".
Here is my function prototype:
void print_path(int previous[], int desired_node_index);
Here is my function:
void print_path(int previous[], int desired_node_index)
{
if( previous[desired_node_index] != -1 )
print_path( previous[desired_node_index] );
printf("-> %d ", previous[desired_node_index]);
}
and here is where I call my function:
print_path(previous, dest_index);
I'm obviously passing it in wrong, or else I'm doing something incorrectly about how to pass an array into a function. Any help?
Thanks guys!
This is obviously a recursive function. Note that print_path() takes 2 parameters: the first is an int array, and the second is an index to a position inside that array.
Calling it:
print_path( previous[desired_node_index] );
is absolutely wrong (unless you have overloaded this function), because it expects 2 parameters and you are only passing it one. What you should be doing is:
print_path( previous, desired_node_index );
What you seem to be missing in this function is an operation to increase/decrease the index variable, else you will always be printing the same position in the array.
Without knowing what is exactly that you are trying to do, there's the possibility that you wanted to do this:
print_path( previous, previous[desired_node_index] );
An obvious error is:
print_path( previous[desired_node_index] );
I'm not sure what you're trying to do, but I guess you want something like:
#include <stdio.h>
void print_path(int *previous, int desired_node_index);
int main(void) {
int dest_index = 2;
int previous[5] = { -1, 0, 1, 2, 3};
print_path(previous, dest_index);
return 0;
}
void print_path(int *previous, int desired_node_index) {
if( previous[desired_node_index] != -1 )
print_path( previous, previous[desired_node_index]);
printf("-> %d ", previous[desired_node_index]);
}
void receive_array(int *temp_arr)
{
int i=0;
do
{
temp_arr[i]=temp_arr[i]+1;
i++;
}
while((char)temp_arr[i]!='\0');
}
here I have made some modifications. The array temp_arr2[] is a buffer array. In my actual program, I printed the array from the main(). Here, for doing the same thing, one need to store back the end result of some computation into temp_arr[].MAX can be a macro or a global variable. In the previous one, I just forgot to edit the lines: temp_arr[i]=temp_arr[i]+1; (my demo sample code) :)
void receive_array(int *temp_arr)
{
int i=0;
int temp_arr2[MAX];
do
{
temp_arr2[i]=temp_arr[i];
i++;
}
while((char)temp_arr[i]!='\0');
}
If you want to pass array to function and return after changing the elements from the function you can see the following example:
You may find the solution at: https://github.com/krishnabhat81/Send-and-return-array-from-function-in-C
#include <stdio.h>
/*
If you want to return a single-dimension array from a function, you would have to
declare a function returning a pointer as in the following example:
*/
int *getRandom(int arr[])
{
static int r[10];
/*Second point to remember is that C does not advocate to return the address of a
local variable to outside of the function so you would have to define the
local variable as static variable.*/
int i;
for ( i = 0; i < 10; ++i)
{
r[i] = arr[i]+1;//rand();
printf( "r[%d] = %d\n", i, r[i]);
}
return r;
}
/* main function to call above defined function */
int main ()
{
/* a pointer to an int */
int *p;
int i;
int arris[10] = {110,22,33,44,5,6,7,8,9,20};
p = getRandom(arris);
for ( i = 0; i < 10; i++ )
{
printf( "*(p + %d) : %d\n", i, *(p + i));
}
return 0;
}
return 0;
}
I have function, it receive pointer to array and pointer to function and should return new array with order defined by function passed in parameter.
My problem how I copy element of one array to another without knowing its type
void * scrambleArr(void * arr, int numElem, int elemSize, int (*func)(void*)) {
void * newArr;
int cPos, newPos,i;
newArr = (void *)malloc(numElem*elemSize);
for (i=0 ; i < numElem ; i++)
{
cPos = i*elemSize;
newPos = func((char*)arr+cPos);
*((char*)newArr+newPos) = *((char*)arr+cPos);
}
return newArr;
}
Function that passed in the last parameter
int posArrayBySize(void *el) {
ARRAY* arr = (ARRAY *)el;
return arr->size - 1;
}
And code in main:
int main( ) {
ARRAY * arrSorted;
int a[2] = {1,2};
int b[3] = {1,1,1};
int c[1] = {9};
int d[4] = {3,3,3,3};
ARRAY arr[4] = {{a,2},{b,3},{c,1},{d,4}};
arrSorted =(ARRAY *)scrambleArr(arr,4,sizeof(ARRAY),posArrayBySize);
free(arrSorted);
return 0;
}
After running arrSorted contain garbage,
Can someone point me, what i miss?
Another option for me is not to copy, just to point one array to elements of other, is it possible?
Thanks.
memcpy is the function you are looking for.
This won't work
*((char*)newArr+newPos) = *((char*)arr+cPos);
because you're dereferencing arr+cPos as it is char, so it will copy only the first byte.