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.
Related
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++;
}
}
Below is a part of an algorithm i was given to use for a project, but as it's my first time to use an algorithm i don't understand the following lines. Please will need your help.
For i=1 to n do
t[i] .mark <-- 0
t[i] .num <-- -1
End
This pseudo code can be translated to C
Use struct
struct cm{
int mark;
int num;
};
#define N 10
int main(void)
{
struct cm t[N];
for (int i=0;i<N;i++){
t[i].mark = 0;
t[i].num = -1;
}
//print your struct elements field
for (int i=0;i<N;i++){
printf("%d: %d, %d\n",i ,t[i].mark, t[i].num);
}
}
We have an array of struct because of we need each element of it have two field of data (i.e. mark,num).
struct cm t[N]; define a N length array of structure cm.
In loop we assign to each field of array elements proper values.
For more readability you can use typedef instead of using struct to define your desire data structure in this case.
typedef vs struct
Use typedef
typedef struct typecm{
int mark;
int num;
}typecm;
#define N 10
int main(void)
{
typecm s[N];
for (int i=0;i<N;i++){
s[i].mark = 0;
s[i].num = -1;
}
//print values
for (int i=0;i<N;i++){
printf("%d: %d, %d\n",i ,s[i].mark, s[i].num);
}
}
The "t" seems to be an array of objects, and "mark" and "num" are properties of the object.
This may help you:
From an array of objects, extract value of a property as array
If i had an array such as int numbers[5] i could assign values to it with numbers[0] = 1 or numbers[3] = 4. Then if i had a struct such as
struct structName
{
int number0;
int number1;
int number2;
};
is there any way to do something like the following (note this is not working code)
int main(void)
{
struct structName name; //how could i declare this to do the following
for(int i = 0; i < 2; i++)
{
name[i] = i; //maybe name.[i]
}
}
so is there a way to write name[ variable ] = someNumber to assign someNumber to say number0 (if variable was 0) or number2 (if variable was 2). ive been looking for days and cant find anything that does this. (maybe i just don't know what to look for)
is there any way to do something like the following
No, there's no way to access the fields of the structure by index. You use the names of the fields instead:
struct structName name;
name.number0 = someNumber;
name.number1 = someOtherNumber;
If you want to access the values by index, use an array instead, even if it's embedded in the structure:
struct structName
{
int numbers[3];
// other fields here
};
Then you can say:
struct structName name;
for (int i = 0; i <= 2, i++) {
name.numbers[i] = i;
}
You could write a function which uses a switch statement that allows you to access fields by index. Something like:
#include<stdio.h>
struct structName{
int number0;
int number1;
int number2;
};
void assign(struct structName * name, int i, int j){
switch(i){
case 0:
name->number0 = j;
break;
case 1:
name->number1 = j;
break;
case 2:
name->number2 = j;
break;
}
}
int main(void){
int i;
struct structName name;
for(i = 0; i <= 2; i++){
assign(&name,i,i);
}
//test:
printf("%d\n",name.number0);
printf("%d\n",name.number1);
printf("%d\n",name.number2);
return 0;
}
(which prints 0,1,2 as expected).
Needless to say, there isn't much point in doing this (as opposed to just having a field which is an array) unless the struct in question is already defined as part of an API or already part of a code base which isn't easily refactored.
Yes, with some weird and inadvisable memory manipulation. You're much better off using an array.
struct structName
{
int numbers[3];
};
int main(void)
{
struct structName name;
for(int i = 0; i <= 2; i++)
{
name.numbers[i] = i;
}
}
Also note that you had some syntax errors in your for loop and an off-by-one error.
Macros with arguments should work
#define name(x) x
So name(1) would become 1. name(2) would become 2 and so on.
In C, there is no spoon.
struct structName name;
int *idx = &name; // First we need a memory address to the struct
for (int i = 0; i < sizeof(name) / sizeof(*idx); ++i) {
// idx[i] == name.numberX
idx[i] = i;
}
Now, if you check the values of name.number0, name.number1, name.number2 you will see they contain the correct values.
This is not a very good way of doing things with structs, but I felt compelled to answer after the top response claims it is impossible.
I have a function
struct Analysis reduce (int n, void* results)
Where n is the number of files to be analyzed, and I'm passing an array of Analysis structs to results.
The Analysis struct is defined as follows:
struct Analysis {
int ascii[128]; //frequency of ascii characters in the file
int lineLength; //longest line in the file
int lineNum; //line number of longest line
char* filename;
}
I've cast the void * as such,
struct Analysis resArray[n];
struct Analysis* ptr = results;
resArray[0] = ptr[0];
but I can't figure out how to iterate through the resArray properly. I've tried
for (i = 0; i < n; i++){
printf("lineLength: %d\n", resArray[i].lineLength);
}
with n = 3, and I'm getting garbage values. resArray[0] is correct, but resArray[1] is an insanely high number and resArray[2] is just 0. Why wouldn't resArray[1] or resArray[2] give the correct values? If I was incrementing the address incorrectly then it would make sense but I'm just accessing the array at a certain index. Pretty lost here!
resArray[0] is correct because there is "something":
resArray[0] = ptr[0];
Other elements are garbage because you didn't set there any values. If you want to copy entire array you need to change copying method to:
for (i = 0; i < n; i++)
{
resArray[i] = ptr[i];
}
You can't assign a pointer to an array directly because they are different typessince array[n] is type struct analysis(*)[n] and ptr is type struct analysis(*). Check here for more info.
Hopefully this code will help you.
#include <stdio.h>
#define d 3
struct Analysis {
int ascii[128];
int lineLength;
int lineNum;
char *filename;
};
struct Analysis Analyses[d];
struct Analysis reduce(int n, void *results) {
struct Analysis resArray[n];
struct Analysis *ptr = results;
for (int i = 0; i < n; i++) {
resArray[i] = ptr[i];
}
for (int i = 0; i < n; i++) {
printf("lineLength: %d\n", ptr[i].lineLength);
}
return *ptr;
}
int main(void) {
struct Analysis a = {{5}, 2, 2, "George"};
struct Analysis b = {{6}, 3, 3, "Peter"};
struct Analysis c = {{7}, 4, 4, "Jane"};
Analyses[0] = a;
Analyses[1] = b;
Analyses[2] = c;
reduce(d, &Analyses);
return 0;
}
You can try it online.
#include <stdio.h>
#include <stdlib.h>
struct student{
char initials[2];
int score;
};
void sort(struct student* students, int n){
/*Sort the n students based on their initials*/
int i, j, replace;
for(i = 0; i < n; i++)
{
for(j = 0; j < n; j++)
{
if(students[j] > students[j+1])
{
replace = students[j];
students[j] = students[j+1];
students[j+1] = replace;
}
}
}
}
int main(){
/*Declare an integer n and assign it a value.*/
int n=10;
/*Allocate memory for n students using malloc.*/
struct student* students = (struct student *)malloc(n*sizeof(struct student));
/*Generate random IDs and scores for the n students, using rand().*/
int i;
for(i=0; i<10; i++){
(students + i)->initials[1] = rand( ) % 26 + 'A';
(students + i)->initials[2] = rand( ) % 26 + 'A';
}
/*Print the contents of the array of n students.*/
for(i=0; i<10; i++){
printf("%c%c\n", students[i].initials[1], students[i].initials[2]);
}
/*Pass this array along with n to the sort() function*/
sort(students, n);
/*Print the contents of the array of n students.*/
return 0;
}
I get the following errors when i compile this code,
Program5.c: In function ‘sort’:
Program5.c:23:23: error: invalid operands to binary > (have ‘struct student’ and ‘struct student’)
if(students[j] > students[j+1])
^
Program5.c:25:17: error: invalid operands to binary == (have ‘int’ and ‘struct student’)
replace == students[j];
^
Program5.c:27:23: error: incompatible types when assigning to type ‘struct student’ from type ‘int’
students[j+1] = replace;
Any help would be highly appreciated :)
The first two errors mean that the compiler can't find a > (greater than) operator or a == (equal to) operator that compares a student to a student. The compiler can't just make one up. You need to write your own > and == operators.
The third error means the compiler can't find an assignment operator (=) that takes a student and assigns it to an int. Again, you need to write that operator, because the compiler doesn't know what you want to happen.
You should be able to find the proper syntax for defining these operators by searching for something along the lines of "define c++ == operator" or "define c++ assignment operator".
Remember that arrays in C/C++ are zero-based, and that you're over-writing memory in the initials generation code.
Also watch your array indices in the inner sorting loop; at some point j+1 will be equal to n, and you'll accessing storage that doesn't belong to you.
Your get your first error because the compiler doesn't know how to compare your student structs, it can't tell how to sort them. You must define the operator for this. For example, if you want to order them by score, you can change your student struct to:
struct student {
char initials[2];
int score;
friend bool operator > (const student& lhs, const student& rhs) {
return lhs.score > rhs.score;
}
};
The other two error are caused because you are trying to assign a student struct to an int (students[j] to replace), and vice-versa. Changing the type of replaceto student should fix this problem.
You need to define the following function:
/** #return 0 - if the students are the same
value greater than 0 - if the first student compares greater than the second
value less than 0 - if the second student compares greater than the first
*/
int cmp_student(const struct student* std1, const struct student* std2);
Then in your sort function you can use this function like so:
void sort(struct student* students, int n){
/*Sort the n students based on their initials*/
int i, j, replace;
for(i = 0; i < n; i++)
{
for(j = 0; j < n; j++)
{
if(cmp_student(&students[j], &students[j+1]) < 0)
{
...
}
}
}
}
Note that there is a problem with the second nested loop in that function. What happens when j == (n - 1), what would the value of j + 1 be?
I would also recommend writing a swap function which takes two index positions and the array and swaps the contents of the array at those two positions. Something like this:
void swap(int id1, int id2, struct student* students);