I have a problem in C. This is the question:
Develop a C function ADDER that adds two integer arrays together. ADDER should have only two parameters, which are the two arrays to be added. The second array argument will hold the sum of arrays on exit. Both parameters should be passed by reference.
Write a C program to test the ADDER function with the call ADDER (A, A) where A is an array to be added to itself. Array A can be of any size with any values. Write, compile, and execute the program.
Explain the results of the program.
So far I have solved it this way and it works just fine:
#include <stdio.h>
// using namespace std;
const int SIZE = 5;
/* Adds two arrays and saves the result in b
* Assumes that b is larger than or equal to a in size
*/
void ADDER(int (&a)[SIZE], int (&b)[SIZE]) {
int aSize, bSize, i; /* variable declaration */
/* find out the sizes first */
aSize = sizeof (a) / sizeof (int);
bSize = sizeof (b) / sizeof (int);
/* add the values into b now */
for (i = 0; i < aSize; i++) {
b[i] = b[i] + a[i];
}
/* we have the sum at the end in b[] */
}
/* Test program for ADDER */
int main() {
int i; /* variable declaration */
int a[] = {1, 2, 3, 4, 5}; /* the first array */
/* add them now */
ADDER(a, a);
/* print results */
printf("\nThe sum of the two arrays is: ");
for (i = 0; i < SIZE; i++) {
printf("%d ", a[i]); /* print each element */
}
return 0;
}
The problem is, I have to use dynamic arrays and use malloc and realloc in the program to compute the size of the array on the fly. Instead of specifying the array size and the elements itself, I want the program to ask the user for input and the user enters the array and the size is determined there. It should all be dynamic. I do not know how this is done. Can anyone please help me out! thanks!
Also I have to explain how the array is added to itself the result is saved in "a" and the original array is lost replaced by the sum. how can I explain this?
Here is how your program would look like
int size; //global variable
void ADDER(int *a, int *b) {
int i;
for (i = 0; i < size; i++) {
b[i] += a[i];
}
}
int main(){
//ask the user to input the size and read the size
int *a = (int *)malloc(size*sizeof(int));
int *b = (int *)malloc(size*sizeof(int));
//fill up the elements
Adder(a,b);
//print out b
free(a->array);
free(b->array);
}
ALthough its not wise to use globals, the bottom line here is that adder somehow needs to know the size of the array and somehow you need to convey the size to the ADDER function. If that can't be done through parameters, you have to use globals.
Another option would be to use structures.
typedef struct myArray{
int *array;
int length;
}ARRAY;
void ADDER(ARRAY *a, ARRAY *b) {
int i;
for (i = 0; i < b->length; i++) {
b->array[i] += a->array[i];
}
}
int main(){
int size; //local variable
//ask the user to input the size and read into the 'size' variable
ARRAY *a, *b;
a->array = (int *)malloc(size*sizeof(int));
b->array = (int *)malloc(size*sizeof(int));
a->length = b->length = size;
//fill up the elements
Adder(a,b);
//print out b.array
free(a->array);
free(b->array);
}
How about something like this:
size_t length;
void ADDER(int *a, int *b)
{
for (int i = 0; i < length; i++)
{
/* Add the arrays */
}
}
int main()
{
/* Get the number of entries in the arrays from the user */
/* Store the result in the global variable "length" */
/* Check the "scanf" function for that */
int *a;
/* Allocate the array */
/* Remember that "malloc" wants the size in bytes, not number of items in the array */
/* Get all items for the array from the user */
/* Now add the array to itself */
ADDER(a, a);
/* Print the result */
/* Free the array, a very important step! */
}
As you can see it's not complete code, but gives hints about what should be done, and where. Hope it helps somewhat.
Edit 2 A note about the word "reference". The usage of references is different in C and C++. The way you declared your ADDER function, with int (&a)[SIZE] uses a C++ feature with the &. In plain C a "reference" is simply a pointer. See this SO question for some good answers about that part.
It is impossible to determine the size of a dynamically allocated array unless you allocate an additional element which works as a sentinel, i.e. contains a value that is never valid in real array elements. Another solution would be putting the number of elements in the first array element.
If you know the size at compile time (and according to your code you do so!), you can simply use the same constant when iterating over the array:
for (i = 0; i < SIZE; i++) {
b[i] += a[i];
}
You will have to read user input in a single int variable. After that you will have to allocate one more space to your int array and then proceed to insert the number to your array.
int main() {
int inpt; //user input.
int inptcnt=0; //amount of numbers given by the user.
char flag='y'; //use this char to know if the user wants to insert another number or no.
int *inptarray; //this pointer will be your int array.
inptarray = (int *) malloc (sizeof(int)); //Here you generate the first entry for your array.
if (inptarray == NULL) { //Never forget to check if Malloc and Realloc failed.
printf("Memory Error!!!\n);
exit(1);
}
while (flag == 'y') {
printf("Please enter a number:");
scanf("%d", inpt); //you ask from the user to input a number
inptcnt++; //You add one to the amount of numbers you have been given.
printf("\nIf you wish to enter another number as well please press 'y'. Press anything else if you dont:");
scanf(" %c", flag);
inptarray[inptcnt - 1] = inpt; //You add the number given by the user to your array.
if (flag != 'y') {
break;
} else {
realloc(inptarray, inptcnt * sizeof(int)); // Here you add space for the new entry to your array.
if (inptarray == NULL) { //Never forget to check if Malloc and Realloc failed.
printf("Memory Error!!!\n);
exit(1);
}
}
}
}
This is how you can generate an array of whatever size you need, according to user input.
You can access the size value of this array through the inptcnt variable. The number that is stored within this variable is the size of your array and the amount of user inputs you have. Also don't forget to call free(inptarray) after you are done using your array to free up the claimed memory.
Related
I have two functions in my main function.
I've tried to accomplish this problem with pointers, but as a beginner, it is very complicated to work with this.
int main(){
int *p;
p = function_A();
function_B(p);
return 0;
}
int function_A(){
static int myArray[3];
myArray[0] = 11;
myArray[1] = 22;
myArray[2] = 33;
return myArray;
}
int function_B(int *myPointer){
// Here I just want to print my array I've got from function_A() to the
// console
printf("%d", *myPointer)
return 0;
}
function_A should return a array and function_B should take this array.
Thanks!
There are some issues your compiler will already have told you.
First, you should define the functions before calling them, or at least forward declare them.
Second, to return an array, you need to return a pointer to the first element of this array, i.e. return type is int * and not int.
Third, as FredK pointed out, when you receive just a pointer, you have no chance to determine how many elements are in the array it points to. You can either terminate the array with a specific value, e.g. 0, or you need to return the size of the array, too.
See the following adaptions made to your program:
int* function_A(int *size){
static int myArray[3];
myArray[0] = 11;
myArray[1] = 22;
myArray[2] = 33;
if (size) {
*size = 3;
}
return myArray;
}
void function_B(int *myPointer, int size){
for (int i=0; i<size; i++) {
printf("%d\n", myPointer[i]);
}
}
int main(){
int *p;
int size=0;
p = function_A(&size);
function_B(p,size);
return 0;
}
Note: a reference to an array degrades to the address of the first byte of the array.
the following proposed code:
cleanly compiles
incorporates the comments to the question
assumes the programmer already knows the size of the array
performs the desired functionality
appended '\n' to format string of calls to printf() so output on separate lines
and now, the proposed code:
#include <stdio.h>
int * function_A( void );
void function_B(int *myPointer);
int main( void )
{
int *p;
p = function_A();
function_B(p);
return 0;
}
int * function_A()
{
static int myArray[3];
myArray[0] = 11;
myArray[1] = 22;
myArray[2] = 33;
return myArray;
}
void function_B(int *myPointer)
{
printf("%d\n", myPointer[0]);
printf("%d\n", myPointer[1]);
printf("%d\n", myPointer[2]);
}
a run of the program produces the following output:
11
22
33
Let's say you have a function that creates an array of ints:
int *create_int_array(const size_t num)
{
int *iarray;
size_t i;
if (num < 1)
return NULL; /* Let's not return an empty array. */
iarray = malloc(num * sizeof iarray[0]);
if (!iarray)
return NULL; /* Out of memory! */
/* Fill in the array with increasing integers. */
for (i = 0; i < num; i++)
iarray[i] = i + 1;
return iarray;
}
Let's say tou have a function that calculates the sum of the integers in the array. If we ignore any overflow issues, it could look like this:
int sum_int_array(const int *iarray, const size_t num)
{
int sum = 0;
size_t i;
/* Sum of an empty array is 0. */
if (num < 1)
return 0;
for (i = 0; i < num; i++)
sum += iarray[i];
return sum;
}
Note that sizeof is not a function, but a C language keyword. Its argument is only examined for its size. Thus, sizeof iarray[0] yields the size of each element in iarray, and is completely safe and valid even if iarray is undefined or NULL at that point. You see that idiom a lot in C programs; learn to read it as "size of first element of iarray", which is the same as "size of each element in iarray", because all C array elements have the exact same size.
In your main(), you could call them thus:
#ifndef NUM
#define NUM 5
#endif
int main(void)
{
int *array, result;
array = create_int_array(NUM);
if (!array) {
fprintf(stderr, "Out of memory!\n");
exit(EXIT_FAILURE);
}
result = sum_int_array(array, NUM);
printf("Sum is %d.\n", result);
free(array);
return EXIT_SUCCESS;
}
As you can see, there is really not much to it. Well, you do need to get familiar with the pointer syntax.
(The rule I like to point out is that when reading pointer types, read the specifiers from right to left, delimited by * read as a pointer to. Thus, int *const a reads as "a is a const, a pointer to int", and const char **b reads as "b is a pointer to a pointer to const char".)
In this kind of situations, a structure describing an array makes much more sense. For example:
typedef struct {
size_t max; /* Maximum number of elements val[] can hold */
size_t num; /* Number of elements in val[] */
int *val;
} iarray;
#define IARRAY_INIT { 0, 0, NULL }
The idea is that you can declare a variable of iarray type just as you would any other variable; but you also initialize those to an empty array using the IARRAY_INIT macro. In other words, thus:
iarray my_array = IARRAY_INIT;
With that initialization, the structure is always initialized to a known state, and we don't need a separate initialization function. We really only need a couple of helper functions:
static inline void iarray_free(iarray *array)
{
if (array) {
free(array->val);
array->max = 0;
array->num = 0;
array->val = NULL;
}
}
/* Try to grow the array dynamically.
Returns the number of elements that can be added right now. */
static inline size_t iarray_need(iarray *array, const size_t more)
{
if (!array)
return 0;
if (array->num + more > array->max) {
size_t max = array->num + more;
void *val;
/* Optional: Growth policy. Instead of allocating exactly
as much memory as needed, we allocate more,
in the hopes that this reduces the number of
realloc() calls, which tend to be a bit slow.
However, we don't want to waste too much
memory by allocating and then not using it. */
if (max < 16) {
/* Always allocate at least 16 elements, */
max = 16;
} else
if (max < 65536) {
/* up to 65535 elements add 50% extra, */
max = (3*max) / 2;
} else {
/* then round up to next multiple of 65536, less 16. */
max = (max | 65535) + 65521;
}
val = realloc(array->val, max * sizeof array->val[0]);
if (!val) {
/* We cannot grow the array. However, the old
array is still intact; realloc() does not
free it if it fails. */
return array->max - array->num;
}
/* Note: the new elements in array->val,
array->val[array->max] to
array->val[max-1], inclusive,
are undefined. That is fine, usually,
but might be important in some special
cases like resizing hash tables or such. */
array->max = max;
array->val = val;
}
return array->max - array->num;
}
/* Optional; same as initializing the variable to IARRAY_INIT. */
static inline void iarray_init(iarray *array)
{
array->max = 0;
array->num = 0;
array->val = NULL;
}
The static inline bit means that the functions are only visible in this compilation unit, and the compiler is free to implement the function directly at the call site. Basically, static inline is used for macro-like functions and accessor functions. If you put the structure in a header file (.h), you'd put the related static inline helper functions in it as well.
The growth policy part is only an example. If you omit the growth policy, and always reallocate to array->num + more elements, your code will call realloc() very often, potentially for every int appended. In most cases, doing it that often will slow down your program, because realloc() (as well as malloc(), calloc()) is kind-of slow. To avoid that, we prefer to pad or round up the allocation a bit: not too much to waste allocated but unused memory, but enough to keep the overall program fast, and not bottlenecked on too many realloc() calls.
A "good growth policy" is very much up to debate, and really depends on the task at hand. The above one should work really well on all current operating systems on desktop machines, laptops, and tablets, when the program needs only one or only a handful of such arrays.
(If a program uses many such arrays, it might implement an iarray_optimize() function, that reallocates the array to exactly the number of elements it has. Whenever an array is unlikely to change size soon, calling that function will ensure not too much memory is sitting unused but allocated in the arrays.)
Let's look at an example function that uses the above. Say, the obvious one: appending an integer to the array:
/* Append an int to the array.
Returns 0 if success, nonzero if an error occurs.
*/
int iarray_append(iarray *array, int value)
{
if (!array)
return -1; /* NULL array specified! */
if (iarray_need(array, 1) < 1)
return -2; /* Not enough memory to grow the array. */
array->val[array->num++] = value;
return 0;
}
Another example function would be one that sorts the ints in an array by ascending or descending value:
static int cmp_int_ascending(const void *ptr1, const void *ptr2)
{
const int val1 = *(const int *)ptr1;
const int val2 = *(const int *)ptr2;
return (val1 < val2) ? -1 :
(val1 > val2) ? +1 : 0;
}
static int cmp_int_descending(const void *ptr1, const void *ptr2)
{
const int val1 = *(const int *)ptr1;
const int val2 = *(const int *)ptr2;
return (val1 < val2) ? +1 :
(val1 > val2) ? -1 : 0;
}
static void iarray_sort(iarray *array, int direction)
{
if (array && array->num > 1) {
if (direction > 0)
qsort(array->val, array->num, sizeof array->val[0],
cmp_int_ascending);
else
if (direction < 0)
qsort(array->val, array->num, sizeof array->val[0],
cmp_int_descending);
}
}
Many new programmers do not realize that the standard C library has that nifty and quite efficient qsort() function for sorting arrays; all it needs is a comparison function. If the direction is positive for iarray_sort(), the array is sorted in ascending order, smallest int first; if direction is negative, then in descending order, largest int first.
A simple example main() that reads in all valid ints from standard input, sorts them, and prints them in ascending order (increasing value):
int main(void)
{
iarray array = IARRAY_INIT;
int value;
size_t i;
while (scanf(" %d", &value) == 1)
if (iarray_append(&array, value)) {
fprintf(stderr, "Out of memory.\n");
exit(EXIT_FAILURE);
}
iarray_sort(&array, +1); /* sort by increasing value */
for (i = 0; i < array.num; i++)
printf("%d\n", array.val[i]);
iarray_free(&array);
return EXIT_SUCCESS;
}
If size of array is indeed 3 (or other small fixed value), then you can simply use structs as values, something like:
struct ints3 {
int values[3];
// if needed, can add other fields
}
int main(){
struct ints3 ints;
ints = function_A();
function_B(&ints);
return 0;
}
// note about function_A signature: void is important,
// because in C empty () means function can take any arguments...
struct ints3 function_A(void) {
// use C designated initialiser syntax to create struct value,
// and return it directly
return (struct ints3){ .values = { 11, 22, 33 } };
}
int function_B(const struct ints3 *ints) {
// pass struct as const pointer to avoid copy,
// though difference to just passing a value in this case is insignificant
// could use for loop, see other answers, but it's just 3 values, so:
printf("%d %d %d\n", ints->values[0], ints->values[1], ints->values[2]);
return 0; // does this function really need return value?
}
The program should do this: write a doubleArray() function, which takes in input an array of int and its size (as a pointer to int). In the main(): ask the user to input an integer n between 1 and 4, then dynamically create an array of size n. Then start filling the array with 2048 randomly generated int: each time the array is full, call the doubleArray function; each time the function doubleArray is called, print the content of the array.
My code works until the size of array n reach a number around 250, then stops inside the for loop.
#include<stdlib.h>
#include<stdio.h>
#include<time.h>
void doubleArray(int vect[], int *dim)
{
int n = *dim *2;
*dim = n;
vect = (int*)realloc(vect, n*sizeof(int));
}
void stampaArray(int vect[], int dim)
{
for (int i=0;i<dim;i++)
{
printf("%d ",vect[i]);
}
printf("\n");
}
int main()
{
printf("Insert a number between 1 and 4: ");
int n;
scanf("%d",&n);
if ((n<1)||(n>4))
{
printf("Number not valid, try again: '");
scanf("%d",&n);
}
int *arr = (int*) malloc (n*sizeof(int));
srand(time(NULL));
int num;
for (int i=0;i<220;i++)
{
num = rand();
if (i==n)
{
doubleArray(arr, &n);
stampaArray(arr, n);
}
arr[i]=num;
}
stampaArray(arr,n);
return 0;
}
Firstly, Change this
if ((n<1)||(n>4)) { } /* use && instead of || to scan if n if both condition are true*/
to
//scanf("%d",&n); /*remove this, use only once, in below loop */
while(1) {
scanf("%d",&n);
if ((n>=1) && (n<=4)) {
break;
}
else {
printf("Number not valid, try again: '");
}
}
And allocate memory equal to n bytes. for e.g
int *arr = malloc (n * sizeof(*arr)); /* typecasting is not required */
Also here
for (int i=0;i<220;i++) { /* some code */ }
what is the rationale behind rotating loop 220 times, doesn't it should be n times ?
As you were said in comment, your main error is that realloc is allowed to change the pointer value. If it happens, the new value is only assigned to the local copy inside the doubleArray function, but the caller still keeps the previous value which is now a dangling pointer (pointing to non allocated memory). Using it invokes Undefined Behaviour (and crashes are to be expected...)
The correct way is to return the new pointer value:
int * doubleArray(int vect[], int *dim)
{
int n = *dim *2;
*dim = n;
return realloc(vect, n*sizeof(int));
}
That is not all. best practices recommend to test allocation. In a stressed environment, the system could be unable to allocate enough memory and realloc could return NULL. Proceeding would then also involve Undefined Behaviour.
Let us go on. Controlling input is nice, but a user can type twice an error, so you should loop until you get a correct value:
int n;
for (;;) {
printf("Insert a number between 1 and 4: ");
scanf("%d",&n);
if ((n >= 1) && (n <= 4)) break;
printf("Number not valid, try again: '");
}
And please, please do not cast malloc in C language. It is useless and can hide hard to find indirection level errors.
Finally, I cannot understand why you have a loop up to 220... From your requirements it should be up to 2048.
Last point (but this one is only my opinion, not a problem): I would only display the initialized content of the array, so up to i instead of n. That way you would see the array grow while always keeping the same (initialized) values:
int *arr = malloc (n*sizeof(int));
srand(time(NULL));
int num;
for (int i=0;i<2048;i++)
{
num = rand();
if (i==n)
{
arr = doubleArray(arr, &n);
if (arr == NULL) {
perror("allocation error");
return 1;
}
stampaArray(arr, i);
printf("\n");
}
arr[i]=num;
}
stampaArray(arr,2048);
free(arr); // not required immediately before a return but good practice
I just learned about pointer and tried the program on the textbook,
"Declare an array of char type with size 8, ask the user to input a
string and then assign to the array. Develop a user-defined
function to sort the array in a non-decreasing order. Print the array
before and after sorting in the main function. The function
prototype is given as
void arr_sort( char * cPtr)"
I don't know very clear what mistake I have made.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void print(char *a[]);
void arr_sort( char *a[]);
int main()
{
int i;
char *array[8];
printf("Please input a string with size 7:");
for(i=0;i<7;i++)
{
scanf("%s",array);
}
printf("the array before sorting is");
print(array);
arr_sort(array);
print(array);
return 0;
}
void arr_sort( char *a[])
{
int i,j;
char *temp;
for(i=0;i<7;i++)
{
for(j=0;j<7;j++)
{
if(strcmp(a[j],a[j+1])>0)
{
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
}
void print(char *a[])
{
int i;
for(i=0;i<7;i++)
{
printf("%s ",a[i]);
}
}
doing a quick 'google' for a bubble sort, in C, results in:
// where 'n' is the number of entries in the array
// where 'array' is declared as 'int array[n];
for ( int c = 0 ; c < ( n - 1 ); c++ )
{
for ( int d = 0 ; d < n - c - 1; d++ )
{
if ( array[d] > array[d+1] ) /* For decreasing order use < */
{
int temp = array[d];
array[d] = array[d+1];
array[d+1] = temp;
}
}
}
Notice the limits on the upper bound of the index variables.
in your program you will be using char rather than int for temp and for the declaration of array[]
notice there is no need for anything in the string.h header file.
notice the limiting of the scope of the local variables c, d, and temp
The comments on your posted question cover the problems in the posted code, so I will not repeat all of them here.
for(i=0;i<7;i++) {
scanf("%s",array);
}
If you want 8 strings of length 7, you can't scanf them into the array. Your array is an array of pointers as defined here:
char *array[8];
Which is very different from this:
char array[8];
The first is an array that stores 8 pointers to strings. The second is an array that stores 8 characters. If you wanted to store a single string, you would do this:
char array[8];
printf("Please input a string with size 7: ");
scanf("%s", array);
Which is probably what you're used to at this point.
So, an array of pointers is just like a list of little arrows that point to blocks of memory. Your array doesn't store any characters itself, which is why you can't scanf directly into it.
int main(void) {
char *arr[8];
char new_word[8];
for(int i = 0; i < 8; i++) {
printf("Enter a new word of length 7: ");
scanf("%s", new_word);
arr[i] = malloc(strlen(new_word) + 1);
strcpy(arr[i], new_word);
}
for(int i = 0; i < 8; i++) {
printf("%s\n", arr[i]);
}
return 0;
}
This program creates two arrays: a pointer array (arr) and a character array (new_word). In the loop, you ask for seven strings of length 7, which is scanf'd into the character array. New memory is set aside for that string with malloc. Then, the string is copied into the block of memory that your first array pointer points to. We increment our array index with the for loop so that now we're using the next pointer, and so on.
It's important to use strcpy and copy the string out of the character array every time, otherwise at the end, you will just have an array of pointers pointing to a single string, new_word.
I'm tasked with writing a function that will identify all the even numbers in an sample array {10,2,9,3,1,98,8] and place them in an array called EvenNumbers. I have to allow the function so that it works with different combinations of numbers in the array not just the numbers in the sample array above.
I'm wondering is there any way to add numbers to an array that could be different every time? How would I extract the even numbers an place them into an array? Also
for the even array size its giving me an error that the expression must have a constant value but when I use const int it still gives me that error.
Here is the full question.
"Using the array of sample values {10,2,9,3,1,98,8}, write a function that will identify all the even numbers in an array and place it in an array called EvenNumbers. The function must work in all cases, not just in the case of the array shown. Assume that the array size is always available through a global constant called MAX"
Here is what I have so far. I've no idea how I will extract the even numbers from a for loop and place them in an array. I also dont know what the "expression must have a constant value" is about?
#include <stdio.h>
#include <stdlib.h>
void EvenNumber(int Array[], int size);
int main()
{
int array[7] = { 10,2,9,3,1,98,8 };
EvenNumber(array, 7);
}
void EvenNumber(int Array[], int size)
{
int i;
int EvenArraySize;
for (i = 0; i < size; i++)
{
if (Array[i] % 2 == 0)
{
EvenArraySize++;
}
}
int Even[EvenArraySize];
}
The right way to go is to use malloc to allocate just the right amount of memory.
Count the number of even numbers
Allocate the space needed to store them
Copy even numbers in this space
Do whatever you want with these numbers
Free the allocated space
Snippet:
#include <stdio.h>
#include <stdlib.h>
#define MAX 7
int
main()
{
int array[] = {10,2,9,3,1,98,8};
int *even_numbers;
int i, nb_even_numbers;
for (i = 0, nb_even_numbers = 0; i < MAX; i++)
{
if (array[i] % 2 == 0)
nb_even_numbers++;
}
even_numbers = malloc(sizeof(int) * nb_even_numbers);
if (!even_numbers)
{
perror("malloc");
return 1;
}
for (i = 0, nb_even_numbers = 0; i < MAX; i++)
{
if (array[i] % 2 == 0)
even_numbers[nb_even_numbers++] = array[i];
}
/* do your stuff here */
free(even_numbers);
return 0;
}
First, you can never return a statically declared array from a function (even though you don't explicitly try, your Even array is destroyed when EvenNumber returns) Why? The function stack frame for EvenNumber is released for reuse on return and any locally declared arrays are no longer valid.
You either need to pass a second array as a parameter to EvenNumber, or you can dynamically allocate storage for Even in EvenNumber (with, e.g. malloc or calloc or realloc) and return a pointer to the beginning of the array. (you must also have some way to return the size or use a constant for a max size).
There is no need to use % (modulo) to test whether a number is odd/even. All you need to do is look at bit-0 (little endian). If it is 0, then the number is odd, if it is 1, then its even. Much more efficient than calling modulo which incorporates division.
Finally, main is type int and therefore returns a value.
Putting those pieces together, you can do something simple like the following:
#include <stdio.h>
#include <stdlib.h>
void EvenNumber (int *array, int *even, int size, int *esize);
int main (void)
{
int array[] = { 10,2,9,3,1,98,8 },
i, n = sizeof array / sizeof *array,
even[n], /* a VLA of the same size as array is fine here */
esize = 0;
EvenNumber (array, even, n, &esize);
printf ("array: ");
for (i = 0; i < n; i++)
printf (" %2d", array[i]);
printf ("\neven : ");
for (i = 0; i < esize; i++)
printf (" %2d", even[i]);
putchar ('\n');
return 0;
}
void EvenNumber (int *array, int *even, int size, int *esize)
{
int i;
for (i = 0; i < size; i++)
if ((array[i] & 1) == 0) /* simply looking at bit-0 is all you need */
even[(*esize)++] = array[i];
}
Note: esize is passed as a pointer to EvenNumber and updated within the function so that the number of elements in even are available back in the calling function (main() here).
Example Use/Output
$ ./bin/arrayeven
array: 10 2 9 3 1 98 8
even : 10 2 98 8
Let me know if you have any further questions.
I'm trying to sort a 2d array of pointers using qsort. The only issue I have right now is originally I was using statically declared arrays now switching over to pointers. I'm almost tempted to switch to structs but being stubborn that I can't get this to work.
So far I malloc the 2d array of pointers[array2d[m][3] was the intended size]:
int **array2d;
array2d = (int**)malloc((m)*sizeof(int*));
for(i=0; i<=m; i++)
array2d = [i]=(int*)malloc(3*sizeof(int));
qsort(array2d, m, 3*sizeof(int**),comp);
My compare is:
int comp(const void* left, const void*right)
{
const int *a = *(const int**)left;
const int *b = *(const int**)right;
return a-b;
}
Although I'm not sure how to structure the compare to work with 2d pointers.
From the code snippet you provided I am assuming you were trying to sort each row of the matrix separately. The first thing I noticed is that there is a typo in the memory allocation of columns (2nd index) of the matrix.
Correct memory allocation of a numRow x numColumns matrix would be as follows:
/* loop counter */
int i;
/* dynamic array sizes */
const int numRow = 5;
const int numColumns = 25;
/* allocate the row pointers */
int **dynamic2d = (int **)malloc(numRow * sizeof(int *));
/* for each row pointer */
for(i = 0; i < numRow; i++)
{
/* allocate columns */
dynamic2d[i] = (int *)malloc(numColumns * sizeof(int));
}
Next you won't be able to simply call the qsort(..) method only once. That method expects a "flat" or one-dimensional array. You will need to call the qsort(...) method separately for each row of the matrix. This is demonstrated below:
/* sort array */
for(i = 0; i < numRow; i++)
qsort(dynamic2d[i], numElements, sizeof(int *), comp);
Lastly, you made a mistake with your comparator method. This method has strict rules that need to be followed in order to work correctly. Current specifications say, "The application shall ensure that the function returns an integer less than, equal to, or greater than 0, if the first argument is considered respectively less than, equal to, or greater than the second. If two members compare as equal, their order in the sorted array is unspecified."
This is a simple fix. Simply write the logic to produce those results as seen below:
int comp(const void* firstArg, const void* secondArg)
{
/* get the values of the arguments */
int first = *(int *)firstArg;
int second = *(int *)secondArg;
/* return the value as expected by the qsort() method */
if(first < second)
{
return 1;
}
else if(second < first)
{
return -1;
}
return 0;
}
Last thing to note, this will sort greatest to least. Do not switch the logic around in the comparator if you want least to greatest. The sort will not return accurate results. The correct way to do this is by reading the array from back to front as seen below: You can swap the arguments in the comparator to change the sorting order or read the results from back to front.
int comp(const void* firstArg, const void* secondArg)
{
/* get the values of the arguments */
int first = *(int *)secondArg;
int second = *(int *)firstArg;
...
}
or
/* print greatest to smallest */
for(i = 0; i < numRow; i++)
{
/* start at front and work to back */
for(j = 0; j < numColumns; j++)
printf("%d ", dynamic2d[i][j]);
printf("\n");
}
/* print smallest to greatest */
for(i = 0; i < numRow; i++)
{
/* start at back and work to front */
for(j = numColumns- 1; j >= 0; j--)
printf("%d ", dynamic2d[i][j]);
printf("\n");
}
Hopefully this helps! If you need to sort the entire matrix as a whole... that is a different beast all together.