I am still learning about C programming, and I am having a bit of an issue with my program.
So my structure is declare in q.h file
#define MAXIMUM_LENGTH 80
struct Tsunami {
unsigned int day;
unsigned int month;
unsigned int year;
unsigned fatalities;
double height;
char location[MAXIMUM_LENGTH];
};
and the function that uses qsort is :
double get_median_height(const struct Tsunami* begin, size_t count)
{
double median = 0;
double compare1,compare2;
struct Tsunami* store = (struct Tsunami*) malloc (sizeof(struct Tsunami) * count);
for (int i = 0; i < (int)count; i++)
{
store[i].month = begin[i].month;
store[i].day = begin[i].day;
store[i].year = begin[i].year;
store[i].fatalities = begin[i].fatalities;
store[i].height = begin[i].height;
strcpy(store[i].location, begin[i].location);
}
qsort(store, count, sizeof(Tsunami), compare_events);
if(count % 2 == 0)
{
printf("%ld",count);
compare1 = store[(count/2)].height;
printf("%lf",compare1);
compare2 = store[(count/2) +1].height;
printf("%lf",compare2);
median = (compare1 + compare2)/2;
}
else
{
median = store[(count/2)].height;
}
free(store);
return median;
}
My compare_events code is
int compare_events(const void* first, const void* second)
{
struct Tsunami* first = (struct Tsunami*)first;
struct Tsunami* second = (struct Tsunami*)second;
return (second->height - first->height);
}
For some reason, it does not help me sort out the value of store.height from smallest to largest. Can someone explain to me why? and how should I use the qsort instead?
Your comparison function:
Is backwards. It's supposed to return a number less than zero if first < second, but yours does the opposite. So intuitively it should be return first->height - second->height. However...
As "chux - Reinstate Monica" alluded to in comments, your heights are of type double but the comparison function must return int. So your function implicitly converts their difference to an int, but this conversion always rounds toward zero. Thus any two heights that differ by less than 1 will have a difference less than 1, which will be rounded to zero and qsort will think the two Tsunamis are of equal height, and may put them in the array in any order.
What you really want is something like sign(first->height - second->height). Unfortunately C has no standard sign function, but you can find many possible implementations at Is there a standard sign function (signum, sgn) in C/C++?. (This will also fix another bug, which is that your function will not correctly compare heights whose difference doesn't fit in an int.)
Related
I'm writing some Code that does some basic analysis on data.
The data collected is in an array of structs. It takes the approximate form:
struct page {
int width;
int length;
char name[50];
// etc...
}
struct page pages[100];
I need to write code that finds the smallest width, largest width, smallest length, largest length, etc. So I write code that looks something like this:
int smallestWidth(struct page pages[]){
unsigned int smallest = -1;
(for loop){
if (smallest > pages[i].width) smallest = pages[i].width;
}
return smallest;
}
And then I find that I'm copy-pasting this function and changing tiny details for the other requirements like largest width. And whenever I'm copy-pasting chunks of code, that raises alarm bells for me, and I'm thinking I'm doing it wrong.
But, I'm kind of new to C, so I'm not sure what the right way to approach this is.
How would you write this in C properly (if there is a proper way) that minimizes the amount of code that I'm copy-pasting?
C++ language has overrides and pointer to members that C has not. So the C way would be to use auxilliary functions to extract the correct data and compare them:
int getLength(struct page *page) {
return page->length;
}
int getWidth(struct page *page) {
return page->width;
}
int lesser(int a, int b) {
return a<b;
}
int greater(int a, int b) {
return a>b;
}
typedef int(*extractor)(struct page *p);
typedef int (*comparator)(int a, int b);
int process(struct page * p, int size, extractor ext, comparator cmp) {
// code here the generic part
...
}
int lesserWidth = process(pages, 100, &getWidth, &lesser);
...
But it includes a good deal of boiler plate code, so it may be interesting or not depending on the complexity of the generic part...
I think the following will be classified as a Horrible Hack, however, it satisfies your request. It only works for integers because of the compare.
struct page {
int width;
int length;
// etc...
} pages[100] = {{1,2},{3,4},{5,6}};
int smallestX(struct page pages[], size_t offset)
{
unsigned int smallest = -1, k;
for (int i=0; i<3; i++){
k= *((int *)((char *)(&pages[i])+offset));
if (smallest > k) smallest = k;
}
return smallest;
}
void example(void)
{
printf ("smallest width= %d\n", smallestX(pages, offsetof(struct page, width)));
printf ("smallest length= %d\n", smallestX(pages, offsetof(struct page, length)));
}
Clarification:
It uses the offsetof macro to get the offset of the member from the beginning of the struct. In the function, it now takes the address of the ith element of the array, interprets that as a byte address, adds the offset (which is in bytes), interprets that as a pointer to an int, dereferences that int and uses it in the compare.
Note: it is possible to extend this method to compare any item by providing a compare function as parameter.
I'm passing an array of single-precision floating point values to a function in C. The function has no knowledge of the size of the array and I'd like to keep it that way, primarily because while the underlying array is of course fixed-length I won't always be filling it completely so I'd need to be able to find the end anyway. With a string you use a null-terminator, but with this implementation all possible values are potentially valid. Is the best I can do like a "code word" to mark the end using multiple values in order, something like ASCII 'STOP'? That leaves open the possibility of coincidentally having that code word in the array of valid data...
You'll see array/size pairs being passed around in C a lot, it's really the only way to do this reliably. Even C strings, which are NUL terminated, are often sent with a length parameter to be sure you don't inadvertently walk off the end of the array and into other memory.
This approach also permits you to use substrings, or subsets of the array, instead of being committed to use the whole thing, the problem you're basically trying to solve. Having a terminator is both a blessing and a curse, as anyone who's ever tried to battle a pernicious buffer-overflow bug can attest to.
In your case, the function signature should look like:
void process(float* v, size_t n)
Where v is the array of floating-point values to process and n is how many of them to use. n should be less than or equal to however many valid entries are in the v array.
If you're passing this kind of thing around a lot you may even encapsulate it in a simple struct that defines the data and size. You can then wrap around that some simple allocator/populator tools.
For example:
struct float_array {
float* values;
size_t size;
};
Where you can then define something like:
struct float_array* make_float_array(size_t n);
void free_float_array(struct float_array* f);
You don't need to pass the array maximum length, just the length currently being used for this call along with the pointer.
You can use NAN this way, assuming that's not a valid value for your dataset:
#include <math.h>
float average(float *array)
{
float sum = 0.0; // Declare this as double for better precision
size_t index = 0;
// x == NAN will return false for all x including NAN, so we need
// the function isnan()
while(! isnan(array[index]))
sum += array[index++];
return sum/index;
}
Since you're probably want to do this for many functions, I recommend writing a function for calculating length:
size_t farray_length(float *array)
{
size_t len = 0;
while(! isnan(array[len])) len++;
return len;
}
But the usual way of solving these problems in C is to send the size as a separate parameter.
float average(float *array, size_t size)
{
float sum = 0.0;
for(size_t i=0; i<size; i++)
sum += array[i];
return sum/size;
}
A third way, which can be useful for instance if you're coding a library with objects you don't want the user to mess with directly, is to declare a struct.
struct float_array {
float *array;
size_t size;
}
float average(float_array array) {
...
With a string you use a null-terminator, but with this implementation all possible values are potentially valid.
If all values are valid, a sentinel value cannot be implemented. It's as simple as that (which is why EOF is an integer value that overflows the char type).
The function has no knowledge of the size of the array and I'd like to keep it that way...
Assuming NaN is an invalid value, you could use the isnan() macro to test for a sentinel value.
However, is NaN is a valid value...
I'd need to be able to find the end anyway.
The only option left is to actually pass the array length along with the array.
If you can't add the array length as a separate argument, you could (probably) store the length of the array as the first member - either using a struct (recommended) or using type punning (don't try this at home unless you know what you're doing).
i.e.
typedef struct float_array_s {
unsigned int len;
float f[];
};
static unsigned int float_array_len(float_array_s * arr) { return arr->len; }
static float float_array_index(float_array_s * arr, unsigned int index) { return arr->f[index]; }
There's really no reason to use computation cycles if you can simply pass the length of the valid array length along with the array.
Edit (type punning)
I highly recommend avoiding this approach, since type lengths could cause hard to detect bugs. However...
It's possible to store the length of the array in the first float member, by using the same bytes (memory) to store an integer.
Note that this might crash (or worst, silently fail) if unsigned int is longer than float (which it might be, even though they usually have the same size in bytes).
i.e.
#include "math.h"
#include "stdint.h"
#include "stdio.h"
/* Returns the member at `index`. */
static float float_array_index_get(float *arr, unsigned int index) {
return arr[index + 1];
}
/* Sets the member at `index` to `val. */
static void float_array_index_set(float *arr, unsigned int index, float val) {
arr[index + 1] = val;
}
/* Returns the array's length. */
static unsigned int float_array_length_get(float *arr) {
if (sizeof(unsigned int) > sizeof(float)) {
fprintf(
stderr,
"ERROR: (%s:%d) type size overflow, code won't work on this system\n",
__FILE__, __LINE__);
}
union {
float f;
unsigned int i;
} pn;
pn.f = arr[0];
return pn.i;
}
/* Sets the array's length. */
static void float_array_length_set(float *arr, unsigned int len) {
if (sizeof(unsigned int) > sizeof(float)) {
fprintf(
stderr,
"ERROR: (%s:%d) type size overflow, code won't work on this system\n",
__FILE__, __LINE__);
}
union {
float f;
unsigned int i;
} pn;
pn.i = len;
arr[0] = pn.f;
}
/* Pushes a member to the array, increasing it's length. */
static void float_array_index_push(float *arr, float val) {
unsigned int len = float_array_length_get(arr);
float_array_index_set(arr, len, val);
float_array_length_set(arr, len + 1);
}
/* Pops a member from the array...
* ... returning nan if the member was nan or if the array is empty.
*/
static float float_array_index_pop(float *arr) {
unsigned int len = float_array_length_get(arr);
if (!len)
return nan("");
float_array_length_set(arr, len);
return float_array_index_get(arr, len);
}
P.S.
I hope you'll stick to the simple func(float * arr, size_t len) now that you see how much extra code you need just to avoid passing the length of the array.
I was reading over some of the source code behind pngquant (here)
I got confused when I saw plus-equals seemingly assigning a new value to an array of structs (base += r in the code snippet below):
static void hist_item_sort_range(hist_item base[], unsigned int len, unsigned int sort_start)
{
for(;;) {
const unsigned int l = qsort_partition(base, len), r = l+1;
if (l > 0 && sort_start < l) {
len = l;
}
else if (r < len && sort_start > r) {
base += r; len -= r; sort_start -= r;
}
else break;
}
}
The hist_item definition is given as:
typedef struct {
f_pixel acolor;
float adjusted_weight, // perceptual weight changed to tweak how mediancut selects colors
perceptual_weight; // number of pixels weighted by importance of different areas of the picture
float color_weight; // these two change every time histogram subset is sorted
union {
unsigned int sort_value;
unsigned char likely_colormap_index;
} tmp;
} hist_item;
I apologize ahead of time, because I'm sure to those in the know this must be a really dumb question, but how is plus-equals operating on base, which appears to be an array of structs, and some integer r? It seems to me that this operation should be undefined for the combination of those two types.
I haven't had to write C for almost ten years, and I'm admittedly pretty rusty; however, searching for about thirty minutes only turned up answers to the wrong questions, and any help is appreciated. Thanks!
As explained in What is array decaying?
static void hist_item_sort_range(hist_item base[], unsigned int len, unsigned int sort_start)
becomes
static void hist_item_sort_range(hist_item* base, unsigned int len, unsigned int sort_start)
Where base is a pointer to the first element of the array. Therefore base += r; performs simple pointer arithmetic, i.e.: modifies the pointer to point to an offset of r elements from the start of the array.
Due to the += the original pointer is modified, so any access happens with offset from the now pointed to element.
To use the example from the comment:
After base += 1; accessing the "first" element via &base[0]; yields a pointer to the same element as &base[1]; before the increment
I am working on a non homework question that I just can't solve no matter what I try.
The problem is one from Project Euler that involves solving for even Fibonacci numbers and summing them together, I chose this one as a chance to learn more about functions, pointers, and working with large numbers that would be best served by not copying their value but instead passing a memory address.
I currently have the following:
/*Second attempt at fibo 4mil
problem.*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <float.h>
//MAX is 20 for testing reasons
//Actual value is MAX 0X3D0900
#define MAX 20
//Function will accept even fibo numbers
//then sum them together for output later
void evenCount (double* evenPoint);
int main(void){
double firstVar = 0;
double secondVar = 1;
double thirdVar;
double modVar = 2;
double sumVar;
double count;
for(count = 0; count < MAX; count++){
thirdVar = firstVar + secondVar;
secondVar = firstVar;
firstVar = thirdVar;
if(fmod(firstVar, modVar) == 0){
evenCount(&firstVar);
}
printf("Currently: %.2f\n", firstVar);
}
sumVar = &evenCount();
printf("Final even sum is: %f\n", sumVar);
return 0;
}
void evenCount (double* evenPoint){
double tempOne, tempTwo, tempThree;
tempOne = *evenPoint;
tempThree = tempOne + tempTwo;
tempTwo = tempOne;
tempOne = tempThree;
evenPoint = &tempOne;
}
I can't tell if the data from main() is being properly passed to the evenCount function for them to be summed and have it's value updated to be printed at the end of main().
My questions are:
Do I need a second double pointer in evenCount to pass the final value or can I just reference one value updating it as it loops through?
Does main() need a pointer so that pointer can reference evenCount pointer?
I would really appreciate any help because I have bought a Safari online subscription, have the "C A Reference Manual" sitting next to me but I just can't figure this out. Plus i read over this question and it kind of answered my question, but the person is using multiple function prototypes.
too few arguments to function and can't be used as a function---- beginning C
Thanks to anybody that looks
I am not completely clear about what the evenCount() function is supposed to do.
Fact is that you are calling it the wrong way - sumVar = &evenCount(); is even twice wrong, as it is missing an argument and the & doesn't make sense - and that it doesn't do what you probably want.
Let's have a look:
void evenCount (double* evenPoint){
double tempOne, tempTwo, tempThree;
Here you define three auto variables, but they haven't got a value yet.
tempOne = *evenPoint;
tempThree = tempOne + tempTwo;
What do you expect to be tempTwo here?
tempTwo = tempOne;
tempOne = tempThree;
evenPoint = &tempOne;
You might mean *evenPoint = tempOne here, but I am not sure.
}
I suppose you want a way to make a "step" in terms of Fibonacci numbers. So let's look:
In order to create the "next" Fib number, you need the two previous ones and add them together. So a "step" could be done in a function like
void fibStep(double * curr, double *prev) {
double new = *curr + *prev;
*prev = *curr;
*curr = new;
}
and then
int main(void){
double firstVar = 0;
double secondVar = 1;
double sumVar = 0;
int count; // no need to have this as a double...
for(count = 0; count < MAX; count++){
fibStep(&secondVar, &firstVar);
if(fmod(secondVar, 2) == 0){
sumVar += secondVar);
}
printf("Currently: %.2f\n", secondVar);
}
printf("Final even sum is: %f\n", sumVar);
return 0;
}
I'm not quite sure what evenCount is meant to do as it is. Edit: see below.
From your description of the problem, it seems like you could just do:
int isEven(unsigned int number)
{
return !(number%2);
}
int main()
{
unsigned int first = 1, second = 1, next, sum = 0;
//we already have the first two numbers so start at 2
for(count = 2; count < MAX; count++)
{
next = first+second;
first = second;
second = next;
//we know the starting values are odd (1 & 1) and won't need to be summed so we can test the new value -
if (isEven(second)) //if even (no remainder when dividing by 2)
{ sum+=first;}
}
printf("Final even sum is: %f\n", sum);
}
Note, there is no need for double here (yet). The sum (at n=20) is still far too low to exceed what int can store. (although at this point it is growing quickly)
As for your actual questions:
note: when you don't need a pointer, it is recommended that you don't use one, as all you are going to do is make the code more complex than needed
Do I need a second double pointer in evenCount to pass the final value?
If the function is meant to keep track of the sum, then I'd do it like this:
unsigned int evenSum(unsigned int num = 0)
{
static unsigned int sum = 0; //initialised on first use of function. Value is retained between function calls.
//we test for even here - no longer need to test in calling code
// - making the algorithm simpler
if (isEven(num))
sum += num;
return sum;
}
which can then be called like this:
//adding values:
evenSum( new_value );
//retrieving sum
sum = evenSum();
//or do both:
sum = evenSum( new_value );
If you wanted to store the sum 'locally' though (i.e. as a variable in main, but modify it in the evenSum() function), then yes, you would then need to pass it into the funtion too as a pointer:
void evenSum(unsigned int num, unsigned int * sum)
{
if (isEven(num))
*sum += num;
}
It would be called like this:
sum = 0;
num = 56;
evenSum(num, &sum); //sum is now sum+num
As you pass the address of sum in, when the function de-references it, it modifies the value and not a copy. The number passed in does not need to be passed in as a pointer as it is a (forgetting correct word here, but it means 'basic') type, and passing it by value is actually slightly more efficient as at runtime it can just be loaded into a register, and doesn't rely on memory lookup. Plus, it is easier to read.
Does main() need a pointer so that pointer can reference evenCount pointer?
To be honest, I'm not 100% sure what you are asking here.
If you are asking:
Do I need to store a pointer to the sum in main() to pass into the evenSum() function?
then no.
You can pass a pointer to a 'thing' using the "address of" operator &. I've used it above in the second calling example in the above answer:
unsigned int * sum_pointer = ∑// <--- not needed
evenSum(num, &sum); //sum is now sum+num
^
This passes a pointer to sum
Edit: looking at your code again, is evenCount meant to find the next fibonachi number?
If so, you could do:
void next_fib(unsigned int *previous, unsigned int *current)
{
unsigned int next = *previous+*current;
*previous = *current;
*current = next;
}
And you would call this like so:
unsigned int val1 = 1, val2 = 1;
next_fib(&val1, &val2); //val2 is now the 3rd fib. #
next_fib(&val1, &val2); //val2 is now the 4th fib. #
To add this to my code from above, the program becomes:
int isEven(double number)
{
return !(number%2);
}
unsigned int evenSum(double num = 0)
{
static double sum = 0;
//we test for even here - no longer need to test in calling code
// - making the algorithm simpler
if (isEven(num))
sum += num;
return sum;
}
void next_fib(unsigned int *previous, unsigned int *current)
{
unsigned int next = *previous+*current;
*previous = *current;
*current = next;
}
int main()
{
unsigned int first = 1, second = 1;
//we already have the first two numbers so start at 2
for(count = 2; count < MAX; count++)
{
next_fib(&first, &second);
evenSum(second);
}
printf("Final even sum is: %f\n", evenSum());
}
Edit 2:
After reading your edit and some of your comments, and then taking a look at the actual task, you have interpreted the question incorrectly.
The question asks for the sum of all even numbers in the fibbonachi sequence, where the number is less than 4x106. This is thankfully easier and quicker to do than the sum of all the even Fibonacci numbers up to the 4x106th.
Obviously, we need to change the algorithm. Luckily, we split the main bits into functions already, so it's pretty simple, mainly just a change in the loops, though I made a couple more changes too:
bool isEven(unsigned long number)
{
return !(number%2);
}
void next_even_fib(unsigned long *previous, unsigned long *current)
{
do
{
unsigned int next = *previous+*current;
*previous = *current;
*current = next;
} while (!isEven( *current));
//we could just do 3 passes here without needing the isEven() function
//as the Fibonacci sequence is always O,O,E,O,O,E...
//but this is a more general form
}
int main()
{
//as there is less constraint on knowing which term we are on, we can skip straight to the first even number.
unsigned long first = 1, second = 2;
unsigned long sum = 0;
do
{
//with the sum calculation first, we can break out of the loop before the sum
//we've changed the algorithm so when we get here, second is always even
sum += second;
next_even_fib(&first, &second);
} while (second < 4000000);
printf("Final even sum is: %d\n", sum);
}
Note that I changed the types to unsigned long. This is still an integer value, but one that is guaranteed to be long ( :-P ) enough to store the numbers we need.
Passing of the value is correct but you can't do evenPoint = &tempOne; to return a value from the function. There are two problems in doing that: first is that C supports only pass by value, so when you pass a pointer you are in fact creating a copy of the pointer for the callee. Any modification of the data pointed will be visible to the caller but not modifications to the pointer argument itself. When you modify the pointer argument you are in fact modifying a stack variable that the caller has no access to.
What's the difference between passing by reference vs. passing by value?
You could change your code in the following way:
void evenCount (double** evenPoint){
double tempOne, tempTwo, tempThree;
tempOne = **evenPoint;
tempThree = tempOne + tempTwo;
tempTwo = tempOne;
tempOne = tempThree;
*evenPoint = &tempOne;
}
But that would mean that *evenPoint points to a variable allocated on the stack, precisely on the frame of evenCount. When evenCount returns the frame get popped out of the stack. Accessing that variable after it is outside the stack will cause undefined behavior.
Consider the following example where you call another function A() after evenCount before using evenPoint. A() function frame would be placed in memory at the same location of where evenCount frame was and its local variables might overwrite the value of evenPoint. When you subsequently read evenPoint you will find its value changed.
C++ Returning reference to local variable
Finally, you read the variable tempTwo which is an uninitialized automatic variable so you'll end up reading garbage.
I'm following LCTHW tutorial and I have a task to do.
This is the data structure:
typedef struct DArray {
int end;
int max;
size_t element_size;
size_t expand_rate;
void **contents;
} DArray;
I have declared a typedef:
typedef int (*DArray_compare) (const void *a, const void *b);
When I create a sorting function, I pass to it a DArray_compare, the problem is that I can't figure out how to do an example of this comparator.
I tried to do something like this:
int compare(const void *a, const void *b)
{
int i = (int)*a;
int k = (int)*b;
printf("%d %d\n", i, k);
return i - k;
}
But I get an error:
error: operand of type 'void' where arithmetic or pointer type is required int i = (int)*a;
The question is: without changing the struct and the typedef of the comparator, I want to create a comparator that compares int, how can I do it?
int i = *(int*)a;
// This one has more parens to make it really obvious what your intent is.
int k = *((int*)b);
The second line (k=) is easiest to explain cos of all the brackets. You can rewrite it as follows:
// Cast b from a pointer to a void into a pointer to an int.
int *X = (int*)b;
// k = "what X is pointing to" or "the contents of X"
int k = *X;
edit:
I think ralu's comment is suggesting you change all the void* to int* which is a much safer solution if you have that power.
typedef int (*DArray_compare) (const int *a, const int *b);
int compare(const int *a, const int *b)
{
int i = *a;
int k = *b;
...
A comparison function for use with bsearch() or qsort() from the standard C library for arrays of DArray structures might look like:
int compare(const void *a, const void *b)
{
const DArray *d1 = a;
const DArray *d2 = b;
if (d1->end < d2->end)
return -1;
else if (d1->end > d2->end)
return +1;
else if (d1->max < d2->max)
return -1;
else if (d2->max > d2->max)
return +1;
else
return 0;
}
Clearly, if you need to compare other fields, you can add those comparisons into the framework above quite easily. The general structure of the function is my recommended way of writing such comparators. You can add explicit casts to the assignment lines if you wish; C++ would require them, but C does not.
Note that your typedef is of minimal relevance to the comparator itself (though the comparator as a function pointer should match that typedef). It is the type that a comparator should have, but you can't use that typedef name when writing the function. You could use the typedef in the implementation of the sort function and in its declaration.
I observed in a couple of places that returning the difference of two signed int values as the result of the comparator leads to undefined behaviour.
In a comment to a now deleted answer, AR89 asked:
Instead of the subtraction an if statement would be safer?
Yes. Consider what happens if you have 16-bit int values and you compare -30,000 and +30,000; you've got signed overflow, and you might get a positive value back from your comparator, even though the first value is less than the second. Analogous situations can occur with 32-bit or 64-bit integers. They're relatively unlikely; if you know that your values are well within range, you'd be OK. But for general purpose code, you should do the piecewise comparison:
if (i < k)
return -1;
else if (i > k)
return +1;
else
return 0;
as it works regardless of the values of i and k. Also note that the if comparison works reliably for unsigned int types too, whereas subtraction really doesn't work then (the result is always zero or positive).