I am working on a simple in-place fourier transform. But I do not know how does the in-place take place. For example the following code snippet, taken from https://rosettacode.org/wiki/Fast_Fourier_transform#C
As the function declares void fft(cplx buf[], int n), without any output, how could the change in buf in the sub-function transfer back into the main function?
#include <stdio.h>
#include <math.h>
#include <complex.h>
double PI;
typedef double complex cplx;
void _fft(cplx buf[], cplx out[], int n, int step)
{
if (step < n) {
_fft(out, buf, n, step * 2);
_fft(out + step, buf + step, n, step * 2);
for (int i = 0; i < n; i += 2 * step) {
cplx t = cexp(-I * PI * i / n) * out[i + step];
buf[i / 2] = out[i] + t;
buf[(i + n)/2] = out[i] - t;
}
}
}
void fft(cplx buf[], int n)
{
cplx out[n];
for (int i = 0; i < n; i++) out[i] = buf[i];
_fft(buf, out, n, 1);
}
void show(const char * s, cplx buf[]) {
printf("%s", s);
for (int i = 0; i < 8; i++)
if (!cimag(buf[i]))
printf("%g ", creal(buf[i]));
else
printf("(%g, %g) ", creal(buf[i]), cimag(buf[i]));
}
int main()
{
PI = atan2(1, 1) * 4;
cplx buf[] = {1, 1, 1, 1, 0, 0, 0, 0};
show("Data: ", buf);
fft(buf, 8);
show("\nFFT : ", buf);
return 0;
}
I am not sure whether I have made the question clear. I wrote a snippet below, with just the same structure with the one above. However, it does not work in in-place mode, by which I mean, the value changes of variable in the sub-function did not transfer into the main function.
#include <stdio.h>
void _sumab(int a, int b, int c)
{
printf("2: %d, %d, %d\n", a, b, c );
a = 2*a + b+c;
b = 12;
// if(a<800) _sumab(a, b, c);
printf("3: %d, %d, %d\n", a, b, c );
}
void sumab(int a, int b, int c)
{
printf("1: %d, %d, %d\n", a, b, c );
_sumab(a, b, c);
a = a*4;
printf("4: %d, %d, %d\n", a, b, c);
}
int main()
{
int out1 = 0;
int out2 = 1;
int out3 = 2;
sumab(out1+100, out2, out3);
printf("5: %d, %d, %d\n", out1, out2, out3);
return 0;
}
in the former code, after calling the sub-function, the value stored in buf changes, even in the main function. but in the latter code, after calling the sub-function, the values of a, b, c remain the same, as they are in the main function scope. Why?
Did I left some important issue or something else? How does the in-place take place?
and if fft(buf, 8) means calculate the fourier transform of buf and store it still in buf, how about the expression fft(buf+2, 8), it will calculate the fourier transform of buf+2, but stores in where?
Thanks in advance.
The key to your question is that in C, you can't pass an array to a function.
When you write this:
void fft(cplx buf[], int n)
The types in that declaration are adjusted * according to the rules defined in §6.7.6.3 p7 of the C11 standard (citing the latest public draft, n1570, here):
A declaration of a parameter as ‘‘array of type’’ shall be adjusted to ‘‘qualified pointer to
type’’, where the type qualifiers (if any) are those specified within the [ and ] of the
array type derivation. [...]
This means, the real declaration looks like this:
void fft(cplx *buf, int n)
So, you're actually passing a pointer and the function can manipulate the original array through that pointer.
*) It's often said the array decays as a pointer. This is not the official wording of the standard, but widely understood. If you have an array like this:
char a[5];
and you just write a, this is evaluated as a pointer to the first element of a, of type char *. So, with a function declared like this:
void foo(char x[]);
you can just call it like
foo(a);
and what really gets passed is the pointer to the first element of a, therefore, a "decays" as a pointer.
Related
#include <stdio.h>
int *max(int *, int *);
int main()
{
int *p, i, j;
p = max(&i, &j);
printf("%d\n", i);
return 0;
}
int *max(int *a, int *b)
{
if(*a > *b)
return a;
else
return b;
}
This is a program intended to return an integer that is bigger. A function "max" returns a pointer, as you can see. I want to print an actual integer here, but I'm stuck and cannot find a proper way to accomplish it. Can somebody help or give some hint to solve my problem?
Also, I would love to know that why there should be an asterisk in front of the function "max". Should there always be an asterisk when a function returns a pointer? The book that I am currently studying lacks information about this specific part, so can someone scratch my back? ;)
Last question first - max returns the value of either a or b. Since both a and b have type int * (pointer to int), then the return type of max also needs to be int *.
To access the integer value, you would need to dereference the result of max:
int main()
{
int *p, i, j;
/**
* The values of i and j are indeterminate at this point;
* you need to assign valid values to them before calling
* max.
*/
i = some_value();
j = some_other_value();
p = max(&i, &j);
printf("%d\n", *p); // Dereference p here to print the int value
return 0;
}
Another way to look at it is that the expressions *a, *b, *p, and *max( &i, &j ) all have type int.
If you want max to return an int rather than an int *, then you will need to dereference a and b in the return statements:
int max( int *a, int *b )
{
if ( *a > *b )
return *a;
else
return *b;
}
Although...
It's not clear why you're passing pointers as arguments to max; you're not attempting to modify the values of a or b, so there's really no need to use pointers at all. Just define max as
int max( int a, int b )
{
if ( a > b )
return a;
return b;
}
and call it as
int m = max( i, j );
or even
printf( "max( %d, %d ) = %d\n", i, j, max( i, j ) );
Hello guys i have a situation here am trying to sort out numbers in C language but i seem to struggle to put a sort function can you please help me with this following souce code that prints out number and supose to sort them but i cant...please help:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num1 = 8, num2 = 6, num3 = 2, num4 = 4, num5 = 1;
printf("%d %d %d %d %d", num1, num2, num3, num4, num5);
// qsort(); THIS IS WHAT I STRUGGLE WITH AT THE MOMENT
return 0;
} // THIS CODE PRINTS OUT NUMBERS BUT ARE NOT SORTED...SO I NEED TO SORT THEM PLEASE
// YOUR HELP WILL BE MUCH APPRECIATED
// I NEED TO KNOW HOW TO USE THE SORT(qsort) FUNCTION
qsort() does one thing and it does it exceptionally well, it sorts arrays, and does so very efficiently. As noted in the comments, before you can use qsort() you will need to collect your values in an array rather than separate variables. Once you have an array, using qsort() is trivial, your only responsibility using qsort is to write the compare() function.
New users of qsort() usually have their eyes roll back in their heads when they see the declaration for the function:
int compare (const void *a, const void *b) { ... }
It's actually quite simple. a and b are simply pointers to elements of the array to compare. Since qsort() can handle any type array, the parameter type are void pointers. If you have an array of int, a and b are just pointers int (e.g. int*). You simply need to write your compare function to cast a and b to int* and dereference to compare the int values with each other.
The return of compare() is either less than zero (a sorts before b), zero (a and b are equal) or greater than zero (b sorts before a). So a niave compare() can be as simple as:
int compare (const void *a, const void *b)
{
int x = *(int *)a,
y = *(int *)b;
return x - y;
}
However, there is always a potential for x - y to overflow with a large negative x and large y or large x and large negative y. So you generally try and use the differnce between two comparisons to eliminate the potential for overflow, e.g.
int compare (const void *a, const void *b)
{
int x = *(int *)a,
y = *(int *)b;
return (x > y) - (x < y);
}
Now if you take any value of a and b the return will either be -1, 0 or 1 providing the sort information for qsort() without chance of overflow.
A short example using your values could be written as:
#include <stdio.h>
#include <stdlib.h>
int compare (const void *a, const void *b)
{
int x = *(int *)a,
y = *(int *)b;
return (x > y) - (x < y);
}
void prn_arr (int *arr, size_t nmemb)
{
for (size_t i = 0; i < nmemb; i++)
printf (i ? ", %d" : "%d", arr[i]);
putchar ('\n');
}
int main()
{
int num[] = {8, 6, 2, 4, 1};
size_t nmemb = sizeof num / sizeof *num;
puts ("array before sort:\n");
prn_arr (num, nmemb);
qsort (num, nmemb, sizeof *num, compare);
puts ("\narray after sort:\n");
prn_arr (num, nmemb);
}
Example Use/Output
$ ./bin/qsortnum
array before sort:
8, 6, 2, 4, 1
array after sort:
1, 2, 4, 6, 8
Look things over and let me know if you have further questions.
I have discovered a library recently which implements a C++ vector like functionality using fat pointers.
I have tried to replicate a similar behaviour in a short program (see the code below). I can access the array elements fine but when I try to get the number of elements my program prints garbage.
#include <stdio.h>
#include <stdlib.h>
int main()
{
double * a = NULL;
// the data
double b[] = {1, 2, 3, 5};
a = (int *) malloc(sizeof(int) + sizeof(double *));
a[0] = 4;
a++;
a = b;
// will print 1.0 2.0 3.0 5.0
printf("%lf %lf %lf %lf\n", a[0], a[1], a[2], a[3]);
// prints garbage
printf("%d\n", *((int *) a - 1));
// this will fail
free(((int *) a - 1))
return 0;
}
It is likely that the problem lies in the pointer arithmetic part of the code, i.e. (int *) a - 1 points to the wrong address, but I could not figure out why is that the case.
Any help is appreciated.
Packing the length at the beginning of the array is not a fat pointer, but an ill-formed PASCAL array.
int main(fat_pointer);
int main(int argc, char* argv[argc]); // standard signature for main is a fat pointer
A fat pointer is a pointer and an index. The data type of the index is an integral type which guarantees that sizeof index <= sizeof(size_t). In other words, sizeof(int) <= sizeof(size_t) is a mandate for all compliant hosted environment because main demands so. Note that size_t is not defined for freestanding environment.
The problem with _s functions is that they use sal.h from Microsoft which allow the usage of variables before declaration.
char * strcpy_s(char * restrict dest, rsize_t destsz, char const * restrict src);
// fat pointer form fails
char * strcpy_s(char dest[destsz], rsize_t destsz, char const * src);
The fat pointer form fails because destsz is declared afterwards, so it cannot be used. Annex K is horrible because it has usage before declaration in fat pointer form. Look at main where argc is declared before argv; that is the proper way to declare a fat pointer.
#include<stdio.h>
#include<stdlib.h>
void print_vector_double(int len, double d[len])
{
for (int i = 0; i < len; i++)
printf("%lf ", d[i]);
printf("\n");
printf("%d\n", len);
}
int main(int argc, char* argv[argc])
{
// C89 VLA - initialized VLA
double b[] = { 1, 2, 3, 5, };
int b_len = (int)(sizeof b / sizeof b[0]);
print_vector_double(b_len, b);
// C99 VLA - uninitialized VLA
int c_len = b_len;
double c[c_len];
c = b;
print_vector_double(c_len, c);
// Good Old Heap for Dynamic Arrays
int a_len = b_len;
double * a = malloc(a_len * sizeof * a);
double * temp = memcpy(a, b_len * sizeof * b, b);
if (temp != a) exit(EXIT_FAILURE);
print_vector_double(a_len, a);
free(a), a = NULL, a_len = 0;
}
A fat pointer is what you pass to a function. If you are not passing anything to another function, there is no fat pointer.
Cello failed to understand what a fat pointer really is.
I need to write a function that replaces 2 "numeric numbers", of otherwise unknown type.
I don't know the exact type and I can only use 2 parameters.
So this is what I have tried:
void swap(void *p1, void *p2)
{
char p;
char * q1 = (char *)p1;
char * q2 = (char *)p2;
for (int i = 0; i < sizeof(long double); i++)
{
p = q1[i];
q1[i] = q2[i];
q2[i] = p;
}
}
Usage:
double a = 100123000000.2;
double b = 100065450000.3;
printf("a: %1f, b: %1f\n", a, b);
swap(&a, &b)
printf("a: %1f, b: %1f\n", a, b);
This works fine but my question is what if my number is bigger then long double (or there is no one..)
Is my solution OK?
This works fine but my question is what if my number is bigger (?)
Is my solution is OK ?
Code will have trouble unless it knows the exact size. So, no, OP's solution is not OK.
Somehow void swap() needs to know the size of the data to swap.
i can only use 2 parameters.
Code can cheat and put all the data into 1 argument as a compound literal, since C99.
typedef struct {
void *a;
void *b;
size_t sz;
} swap_T;
// Only 1 parameter!!
void swap(swap_T sw) {
unsigned char * q1 = sw.a;
unsigned char * q2 = sw.b;
while (sw.sz > 0) {
sw.sz--;
unsigned char p = q1[sw.sz];
q1[sw.sz] = q2[sw.sz];
q2[sw.sz] = p;
}
}
int main(void) {
double a = 100123000000.2;
double b = 100065450000.3;
printf("a: %g, b: %g\n", a, b);
swap(((swap_T ) { &a, &b, sizeof a } )); // Compound literal
printf("a: %g, b: %g\n", a, b);
return 0;
}
Output
a: 1.00123e+11, b: 1.00065e+11
a: 1.00065e+11, b: 1.00123e+11
Code could wrap the swap(((swap_T ) { &a, &b, sizeof a } )) in a macro that looks like a function call of 2
#define SWAP(a,b) (swap(((swap_T ) { &(a), &(b), sizeof (a) } )))
...
SWAP(a,b);
As long as a is not an expression with a variable logic array (VLA) and with side-effects, the macro should work fine.
Of course, best if a,b are the same type.
Your program should try to retrieve sizeof of its argument to know how many bytes to swap - perhaps as a third argument - you have no way of telling otherwise how big an argument is. With current function you will overwrite memory which will end up badly - especially in a bigger program. For example, consider a following program.
#include <stdio.h>
int main() {
int a[] = {1, 2, 3, 4, 5, 6, 7, 8};
swap(&a[0], &a[4]);
for (int i = 0; i < 8; i++) {
printf("%d\n", a[i]);
}
}
Which will return 5, 6, 7, 8, 1, 2, 3, 4 - which clearly isn't expected - only 0th and 4th array elements should have been swapped.
It's possible to hide getting size behind a macro if needed.
#define SWAP(a, b) swap(&(a), &(b), sizeof(a))
So I'm starting to understand the basics of generic programming in C. I'm currently building a program that says if a value occurs or not in a given sequence of number.
I think that the bug occurs in the cmpValues function. Would anyone point it out? (for example, for want=4 and v={1,2,3,4,5}, the program says that want is not in v)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void *search(const void *x, const void *t, int n, int d, int (*cmpValues)(const void *, const void *)){
char *p = (char *)t;
int i;
for(i=0;i<n;++i)
if(cmpValues(x,p+i*d))
return p+i*d;
return NULL;
}
int cmpValues(const void *a, const void *b){
if((char *)a == (char *)b)
return 1;
return 0;
}
int main() {
FILE *f = fopen("datein.txt", "r");
FILE *g = fopen("dateout.txt", "w");
int *v, n, i, want;
fscanf(f, "%d", &n);
v = (int *)malloc(n * sizeof(int));
for(i = 0; i < n; ++i)
fscanf(f, "%d", v + i);
fscanf(f, "%d", &want);
if(search(&want, v, n, sizeof(int), cmpValues))
fprintf(g, "The value %d is found at position %d.\n\n", want, search(&want, v, n, sizeof(int), cmpValues));
else
fprintf(g, "The value does bot occur in the given sequence.\n\n");
return 0;
}
In cmpValues, you are comparing 2 objects pointed by 2 void pointers (i.e. you don't know their type, nor their size). Let's assume we are having ints, and that an int has 4 bytes, which is usually the case.
Just for the sake of it, let's assume that the a pointer has value 0x100 (i.e. points to a int from 0x100 to 0x103, inclusive) and b pointer has a value of 0x104 (i.e. points to the int from 0x104 to 0x107).
Now, you are converting them to char* (char has 1 byte) and compare the value of the pointers. Now, the type of the pointer does not matter in comparisons. In that comparison, you will compare memory addresses (in my example, 0x100 and 0x104). Obviously, the only way the function will return 1 is if the pointers would point to the same variable.
Now, in order to fix it, you should compare the values at the memory addresses pointed by your pointers. However, simply dereferencing the pointers:
*((char *)a) == *((char *)b)
won't be enough, since this would compare just the first byte of a with the first byte of b (under the assumption that char has 1 byte). Also, you can't dereference void*.
So, you need to iterate over your variables and compare them byte by byte (this assumes that you know the size of the data type):
int comp(void *a, void *b, int size) {
// convert a and b to char* (1 byte data type)
char *ca = a;
char *cb = b;
// iterate over size bytes and try to find a difference
for (int i = 0; i < size; i++) {
if (*(ca + i) != *(cb + j)) {
return 0;
}
}
// if no difference has been found, the elements are equal
return 1;
}
side note: you don't need to call cauta twice in main.