I am using stack to make a map function, also the struct seq are opaque structures so I can't really use that. I just don't understand why my item in the struct sequence doesn't update with new values
sequence_item_at: is a function that gets the specific item in the stack based on its index
and sequence_length finds the length of that stack
void sequence_map(struct sequence *seq, int (*func)(int)) {
int length = sequence_length(seq);
int i =0;
while(i < length){
int item = sequence_item_at(seq,i);
int l = func(item);
item = l;
i++;
}
}
Related
I have a lot of records formed by 4 parameters each one.
I have to create an InsertionSort function with each field of the record, but I have three problems:
In first parameter of InsertionSort what can I write in order to pass him the pointer parameter (Is it correct give him directly struct fields *records?)
I have 4 parameters and I have to order them one by one. But, they're 4 different types and I need a generic InsertionSort. With this configuration, how can I pass those parameters? (I tried to put a generic variable void* temp but it doesn't work)
Last one, I have to pass 3 parameters in InsertionSort function. One of them (word) is the field that I must use in order to sort my records.
I hope I was clear. If not, tell me in the comment.
main.c
struct fields{
int id;
char field1[20];
int field2;
float field3;
};
int size; //number of records
struct fields *records = malloc(size * sizeof *records);
/* I fill records with my values */
InsertionSort(records, field1, size); //Here , I need to order my records by field1
InsertionSort function:
void InsertionSort(struct fields *records, char word, int size) { // point 1 and 3
int i, j;
void* temp; // point 2)
for (i = 1; i < size; i++) {
temp = records[i].word;
j = i - 1;
while (j >= 0 && records[j].word > temp) {
records[j + 1].word = records[j].word;
j--;
}
records[j + 1].word = temp;
}
}
I have two identical arrays of struct , one in reverse order.
The problem is that i don't want duplicate the same data into the two arrays , i would a reversed array with elements pointing elements of the first array in a way that i can edit the members of struct of first array or from the reversed array taking effect in both.
you can view the source and run it online here https://onlinegdb.com/SJbepdWxS
#include <stdio.h>
typedef struct point{
int id;
float x,y,z;
} point;
void printPoints(point *pts,int len){
int i = 0;
while (pts !=NULL && i < len){
printf("id %d x %f y%f z %f\n",pts->id,pts->x,pts->y,pts->z);
pts++;
i++;
}
}
void translatePoints(point *pts,int len,float t){
int i = 0;
while (pts !=NULL && i < len){
pts->x = pts->x + t;
pts->y = pts->y + t;
pts->z = pts->z + t;
pts++;
i++;
}
}
void reversePoints(point *pts, int len, point *rev){
int i = 0;
int j = len;
while (i < len){
j=len-i-1;
rev[j]=pts[i];
i++;
}
}
int main()
{
int i;
int t1=200;
int t2=300;
int len=3;
point points[len];
point rev_points[len];
for(i=0; i<len ; i++){
points[i].id=i;
points[i].x=10+i;
points[i].y=20+i;
points[i].z=30+i;
}
//point * pts = points;
printf("\nprint points \n\n");
printPoints(points,len);
printf("\ntranslate points %d...\n\n",t1);
translatePoints(points,len,t1);
printf("\nprint points\n\n");
printf("\nreverse points to rev_points\n");
reversePoints(points,len,rev_points);
printf("\nprint rev_points \n\n");
printPoints(rev_points,len);
printf("\ntranslate rev_points %d...\n\n",t2);
translatePoints(rev_points,len,t2);
printf("\nprint rev_points\n\n");
printPoints(rev_points,len);
printf("\nprint points\n\n");
printPoints(points,len);
return 0;
}
I expect that struct values of both arrays change when i change value in one of the two array.
But changing values of struct in the first array , the second array not changes and the other way around.
One way to look at this is a set of points and two permutations on the set. This sets up a points array, which is used as a set, and forward_points and reverse_points as arrays of pointers to the point array that we are going to use as permutations.
#include <stdio.h>
struct Point {
int id;
float x,y,z;
};
/* Print a point. */
static void printPoint(struct Point *point) {
printf("id %d x %f y%f z %f\n",point->id,point->x,point->y,point->z);
}
/* These print out an array of pointers to point. */
static void printPointsRef(struct Point **ref, int len) {
struct Point **end = ref + len;
while(ref < end) printPoint(*(ref++));
}
/* This translates all the `pts` up to `len` by `(1,1,1)*t`. */
static void translatePoints(struct Point *pts, int len, float t) {
struct Point *end = pts + len;
while(pts < end) {
pts->x = pts->x + t;
pts->y = pts->y + t;
pts->z = pts->z + t;
pts++;
}
}
/* Helper function to `main`. */
static void printPoints(struct Point **forward_points,
struct Point **reverse_points, int len) {
printf("print points\nprint points forward:\n");
printPointsRef(forward_points,len);
printf("print points reverse:\n");
printPointsRef(reverse_points,len);
printf("\n");
}
int main(void)
{
const int len = 3;
/* This is the actual points structure. */
struct Point points[len];
/* These are arrays of pointers to points; they are
permutations of `points`. */
struct Point *forward_points[len], *reverse_points[len];
int i;
const int t1=200;
for(i=0; i<len; i++) {
/* Initialise element `i` of `points`. */
points[i].id=i;
points[i].x=10+i;
points[i].y=20+i;
points[i].z=30+i;
/* Initialise element `i` of `forward_points`
to point to `points[i]`, and `backward_points`
to point the other way (it doesn't matter that
the backwards points are uninitialised, they
will be.) */
forward_points[i] = &points[i];
reverse_points[i] = &points[len - 1 - i];
}
printPoints(forward_points, reverse_points, len);
/* Translation is a vector space operation and doesn't
care about order; we just do it on the original points. */
printf("translate points %d...\n\n",t1);
translatePoints(points,len,t1);
printPoints(forward_points, reverse_points, len);
return 0;
}
Of course, there is no integrity constraints on the pointers; nothing stopping one from pointing at anything, null, the same elements, or anything else.
I added an other struct with one element that is a pointer
typedef struct ptr_point{
point * p;
} ptr_point;
I edited the function reversePoints
void reversePoints(point *pts, int len, ptr_point *rev){
// This function is used only to test pointers
int i = 0;
int j = len;
while (i < len){
j=len-i-1;
rev[j].p = &pts[i];
i++;
}
}
and added another function to print ptr_points
void printPtrPoints(ptr_point *pts,int len){
int i = 0;
while (i < len){
printf("id %d x %f y%f z %f\n",pts->p->id,pts->p->x,pts->p->y,pts->p->z);
pts++;
i++;
}
}
and declaring the second array as ptr_point array
ptr_point rev_points[len];
In conclusion : now data in the second array are not replicated but pointing to element structure of the first array.
The need to not replicate data arise in presence of millions of coordinate points that if replicate more than one time , sorting it for example by x, y, z and so on , occupe much memory with the difficulty of managing .
This fix however forces me to use structures->type in order to change the access mode to read or set values.
I don't know if this is the best solution but it has solved the problem for not duplicate the data.
you can run the source with fixes here: https://onlinegdb.com/SknP_i-eS
Thank you all for the advice.
I have to write a C program to do the following:
Write a function that takes three arguments: a pointer to the first
element of a range in an array, a pointer to the element following
the end of a range in an array, and an int value. Have the function
set each element of the array to the int value.
My code is not working. Here is what I have so far. Any help is appreciated.
#include <stdio.h>
#include <iostream>
int listNumbers[3]{ 1,2,3 };
void Sorter(int *first, int * last, int *value);
int * first = &listNumbers[0];
int * last = &listNumbers[2];
int value;
int main() {
printf("your list numbers are:\n");
int i;
for (int i = 0; i < 3; ++i) {
printf("%d", listNumbers[i]);
}
printf("\n");
printf("enter an integer:\n");
scanf_s("%d", &value);
Sorter( first, last, &value);
printf("your new list numbers are:\n");
int j;
for (int j = 0; j < 3; ++j) {
printf("%d", listNumbers[j]);
}
printf("\n");
system("PAUSE");
return 0;
}
void Sorter(int *first, int * last, int *value) {
int i=0;
printf("value = %d\n", &value);
*first = value;
while (i <= *last) {
*(first + i) = value;
i++;
}
}
First, work out the different between the 2 pointers.
int count = last - first + 1;
The compiler will automatically divide by the size of an integer. We add 1 to make the range inclusive. Now just iterate through each element:
for (int i = 0; i < count; i++) {
first[i] = value;
}
Also, why are you passing the value as a pointer? This should just be a value.
void Sorter(int *first, int *last, int value) {
And when you call it...
Sorter(first, last, value);
Your Sorter function does not satisfy the problem criteria. The parameters are supposed to be two pointers into an array, and an int. Your function instead accepts three pointers.
You could nevertheless have made it implement at least the apparent spirit of the exercise, by using the value to which the third argument points as the fill value, but you don't do that. Instead you assign the pointer itself to each array element. That ought to at least elicit a warning from your compiler, and you ought not to be ignoring its warnings, especially when your code it not doing what you think it should.
Furthermore, the last pointer is expected to point to just past the last element to set, but you use it as if it points to an integer offset from the start pointer. This is almost the opposite of the previous problem: here, you need to use the pointer value itself, not the int to which it points.
I've defined a local structure called item. I'm attempting to sort the items in terms of one of the elements, "uprice". When I attempt to switch the elements in the two items after a hit in the sort, I get an odd error saying that my array a[] of struct item pointers does not actually contain struct items. Here is what I have for code and the error following it:
This is the first portion of the code where I define the bsort function and my struct:
void bsort(struct item* a[], int n);
struct item{
int bcode;
int pcode;
float length;
float width;
int sheets;
int scode;
float price;
float uprice;
};
struct item* list;
This is the second portion of the code where I implement my bsort function:
void bsort(struct item* a[], int n)
{
int i, j, temp;
for (i = 0 ; i < n-1; i++)
{
for (j = 0 ; j < n-i-1; j++)
{
if (a[j].uprice > a[j+1].uprice)
{
temp = a[j].bcode;
a[j] = a[j+1].bcode;
a[j+1].bcode = temp;
//Switch each property of the array individually
}
}
}
}
The error message referring to the code within bsort:
price2.c: In function ‘bsort’:
price2.c:54: error: request for member ‘bcode’ in something not a structure or union
price2.c:55: error: request for member ‘bcode’ in something not a structure or union
price2.c:56: error: request for member ‘bcode’ in something not a structure or union
etc...
The way you have it declared, a is an array of pointers to items. That being the case, you'd need to dereference each a[i] properly:
if (a[j]->uprice > a[j+1]->uprice)
{
temp = a[j]->bcode;
a[j] = a[j+1]->bcode;
a[j+1]->bcode = temp;
//Switch each property of the array individually
}
a[j].uprice
It's still a pointer.
I am learning how to use dynamic arrays in C. What I want to do is to create a dynamic array data, and put "1" into the first entry using the function test().
void test(void)
{
data[0] = 1;
}
int main(void)
{
int *data = malloc(4 * sizeof *data);
test();
return 0;
}
This compiles in Visual Studio 2010 but the program crashes when run. Instead of using test(), using data[0] = 1 works.
My (newbie) guess is that I need to pass a pointer to data to function test(). How should I write this?
Attempt
void test(int *data)
{
data[0] = 1;
}
Then, in main use test(data) instead of just test().
Edit
The attempt works. However, is this a "proper" way of doing it?
When you use a local variable in C, (dynamic or static, array or not), you need to pass it to the function that will be using it. That's what's wrong with your initial code, test() doesn't know anything about data.
When you declare an array, (dynamic or static) you can pass it to the function in the same ways. The following code is pretty pointless, but it illustrates that using a dynamic array is really no different than a static array.
void assign_function(int arr[], int len_of_arr, int *arr2, int len_of_arr2);
void print_function(int *arr, int len_of_arr, int arr2[], int len_of_arr2);
int main()
{
int data[2] = {0}; // static array of 2 ints
int *data2 = malloc(3 * sizeof(int)); // dynamic array of 3 ints
assign_function(data, 2, data2, 3);
print_function(data2, 3, data, 2);
free(data2); // One difference is you have to free the memory when you're done
return 0;
}
So we can pass the arrays, be they dynamic or static, via array[] or as a pointer, but we need to pass an int along as well so we know how big the array is.
void assign_function(int arr[], int len_of_arr, int *arr2, int len_of_arr2)
{
int count;
for(count = 0; count < len_of_arr; count++) //This is the static array
arr[count] = count;
for(count = 0; count < len_of_arr2; count++) //This is the dynamic array
arr2[count] = count;
}
Then just for fun I reverse which array is pass in arr and arr2 here, and also how they're accessed:
void print_function(int *arr, int len_of_arr, int arr2[], int len_of_arr2)
{
int count;
for(count = 0; count < len_of_arr; count++) //This is the dynamic array now
printf("arr[%d] = %d\n", count, *(arr+count));
for(count = 0; count < len_of_arr2; count++) //And this is the static array
printf("arr2[%d] = %d\n", count, *(arr2+count));
}
Point being, passing via [] or as a pointer, and accessing via [] or a deferenced pointer is up to you, both are fine, both work. I try to avoid pointers when I can as they tend to be hard to read and more error prone when writing.
You can pass arrays dynamically in two ways :
Using a simple pointer and then using pointer arithmetic to manipulate
void test (int * data, int i)
{
*(data + i) = 1; //This sets data[i] = 1
}
Or this way :
void test(int data[], int i)
{
data[i] = 1; //This is the more familiar notation
}
Either of these ways is the 'proper' way to go about this.
The variable 'data' in test is locally scoped. It's not the same 'data' that is in main. You should pass a pointer to 'data' through the parameters of test().