#include "stdio.h"
void main( )
{
struct {
char initial;
int age;
int grade;
} kids[12], *point, extra;
I am following the tutorial from here http://www.gatesit.org/gitdownloads/C&DS.pdf page 813-22 and I don't quite understand what kids[12], *point, extra; means. From what I know you can initialize variables of the struct after the definition of it like that but why is there an array size 12, a pointer and extra?
Here is the code following it.
int index;
for (index = 0; index < 12; index++)
{
point = kids + index;
point->initial = 'A' + index;
point->age = 16;
point->grade = 84;
}
kids[3].age = kids[5].age = 17;
kids[2].grade = kids[6].grade = 92;
kids[4].grade = 57;
for (index = 0; index < 12; index++)
{
point = kids + index;
printf("%c is %d years old and got a grade of %d\n",
(*point).initial, kids[index].age, point->grade);
}
extra = kids[2]; /* Structure assignment */
extra = *point; /* Structure assignment */
}
struct mystruct {
char initial;
int age;
int grade;
} kids[12], *point, extra;
is equivalent to:
struct mystruct {
char initial;
int age;
int grade;
};
struct mystruct kids[12];
struct mystruct *point;
struct mystruct extra;
In your particular case, your struct doesn't have a tag name, so you actually can't create any instances of it afterwards - this is the only way you could do it, since it's unnamed.
Since here the struct is being defined inside a function, and its definition will only be available in that function, then it's likely you won't need to define any more instances of it, so there's no disadvantage of not having a name. On the other hand, other than having one less name in the tag namespace (and therefore avoiding the possibility of hiding a tag name at file scope), there's no particular advantage to it, either.
struct {
char initial;
int age;
int grade;
} kids[12], *point, extra;
This struct is unnamed.
This creates an array of 12 of this struct, named kids, a pointer to this type of struct named point, and another one of these structs named extra.
For a one-off structure, used only in a few limited places, this is acceptable. In a larger usage case, I would consider this kind of "sloppy", and would prefer to see something like this:
typedef struct {
char initial;
int age;
int grade;
} student_t;
int main() {
student_t kids[12]; // 12 students in the class
student_t* pStudent; // A pointer to a student_t
student_t extra; // The new kid
}
This basically defined an array of 12 elements of the defined struct kids[12], another variable that is a single pointer to the defined struct *point and finally a single instance of the struct extra.
Since the struct doesn't have a name, I suppose you'd have to define all of them at once next to the struct definition.
Equivalently, it could've been something like this:
struct kid {
char initial;
int age;
int grade;
};
struct kid kids[12];
struct kid *pointer;
struct kid extra;
You are declaring a 12 element array of the struct, a variable that is of the struct type, and a pointer to the struct. Then the code shows the different ways in which those types of variables can be used to access the inner pieces of the struct, and how the items can be assigned among each other.
Related
I've seen many questions here about dereferencing pointers to incomplete types but every single one of them is related to not using typedef or to having the structs declared in the .c, not in the header file. I've been trying to fix this for many hours and can't seem to find a way.
stable.h (cannot be changed):
typedef struct stable_s *SymbolTable;
typedef union {
int i;
char *str;
void *p;
} EntryData;
SymbolTable stable_create();
stable.c:
SymbolTable stable_create() {
SymbolTable ht = malloc(sizeof (SymbolTable));
ht->data = malloc(primes[0] * sizeof(Node));
for (int h = 0; h < primes[0]; h++) ht->data[h] = NULL;
ht->n = 0;
ht->prIndex = 0;
return ht;
}
aux.h:
#include "stable.h"
typedef struct {
EntryData *data;
char *str;
void *nxt;
} Node;
typedef struct {
Node **data;
int n;
int prIndex;
} stable_s;
typedef struct {
char **str;
int *val;
int index;
int maxLen;
} answer;
freq.c:
answer *final;
static void init(SymbolTable table){
final = malloc(sizeof(answer));
final->val = malloc(table->n * sizeof(int));
}
int main(int argc, char *argv[]) {
SymbolTable st = stable_create();
init(st);
}
compiler error (using flags -Wall -std=c99 -pedantic -O2 -Wextra):
freq.c:13:30: error: dereferencing pointer to incomplete type ‘struct stable_s’
final->val = malloc(table->n * sizeof(int));
This code
typedef struct stable_s *SymbolTable;
defines the type SymbolTable as a pointer to struct stable_s.
This code
typedef struct {
Node **data;
int n;
int prIndex;
} stable_s;
defines a structure of type stable_s. Note that stable_s is not struct stable_s.
A simple
struct stable_s {
Node **data;
int n;
int prIndex;
};
without the typedef will solve your problem.
See C : typedef struct name {...}; VS typedef struct{...} name;
As Andrew points out, declaring a "struct stable_s { ... }" will make things compile.
However, you don't say whether this is a class assignment or real-world. If real-world, it's probably an extremely bad idea to declare the struct yourself. You are being given an opaque type to use to reference a library; you are not supposed to know or access the stuff inside. The library is relying on various semantics that you might mess up, and as software versions change, the contents of the struct can (and almost certainly will) change, so your code will break in the future.
I have a struct that defined like that:
typedef struct my_struct
{
int numbers[10];
}
*my_struct;
Is there a way to find out its size?
sizeof(my_struct);// return size of a pointer
The struct type itself is spelled with struct, so you can say:
sizeof (struct my_struct)
This would not work if you hadn't also given your struct a name, which would have been possible:
typedef struct { int numbers[10]; } * foo; /* struct type has no name */
foo p = malloc(1000);
p->numbers[3] = 81;
I'd say all of this is poor code that is needlessly terse for no reason. I would just keep all the names unique, and name everything, and not alias pointers, for that matter. For example:
typedef struct my_struct_s my_struct;
my_struct * create_my_struct(void);
void destroy_my_struct(my_struct * p);
struct my_struct_s
{
int numbers[10];
};
Everything has a unique name, the typedef is separate from the struct definition, and pointers are explicit.
I have a function called SemCreate that takes a name an int and a pointer as parameters. I want the pointer to point to a new struct and I want to return an int, 0 if it went okay.
int P1_SemCreate(char *name, unsigned int value, P1_Semaphore *sem){
USLOSS_Console("Create a semaphore\n");
if(!verifyKernel()) {
//USLOSS_Console("ERROR: Not currently in Kernel mode\n");
USLOSS_Halt(1);
}
if(numSems>= P1_MAXSEM){
//USLOSS_Console("ERROR: MAX semaphore already exist\n");
return -2;
}
if(name == NULL){
return -3;
}
interruptsOff();
int i;
for (i = 0; i < P1_MAXSEM; i++) {
if (semTable[i].inUse == 0) {
semTable[i].value = value;
semTable[i].list = NULL;
semTable[i].name = malloc(sizeof(char));
strcpy(semTable[i].name, name);
semTable[i].inUse = 1;
semaphore *temp = NULL;
temp = malloc(sizeof(semaphore));
temp->value = value;
temp->list = NULL;
temp->name = malloc(sizeof(char));
strcpy(temp->name, name);
*sem = temp;
break;
}
}
numSems++;
interruptsOn();
return 0;
}
Right now the pointer is fine within the function but once I return the pointer is null
EDIT: The array semTable is an array of semaphores
typedef struct semaphore{
int value;
char * name;
struct node *list;
int checkPoint;
int inUse;
}semaphore;
typedef struct PCB {
USLOSS_Context context;
int (*startFunc)(void *); /* Starting function */
void *startArg; /* Arg to starting function */
int pid;
int status;
int killedStatus;
int state;
int priority;
char name[50];
int parentPID;
int numOfChild;
int blockFlag;
struct sempahore *blockSem;
char *stack;
struct node *children;
struct node *zombiList;
int cpuTime;
int startTime;
struct semaphore *childSem;
} PCB;
typedef struct node {
PCB *pcb;
struct node *next;
} Node;
Your question is not perfectly clear as to what you are trying to do. So, this answer addresses the following general topics in hopes they will assist:
1) Passing the address of a struct via a function, changing the values of the struct members, and accessing changed values in calling function. (It is not the same as the one you show, but illustrates what you want to do.)
2) Creating instances and pointers to instances of a struct, then initializing.
3) Contains link to tutorial on self referencing structs. (as you are doing in your posted code)
typedef struct {//struct definition created in global space, typedef'ed
char line[80]; //to read in the line
int slot;
char type[20]; //long enough for any types listed
int position;
}SLOT;
int modifyStruct(SLOT *slot);//prototype of demonstration function
int main(void)
{
SLOT s;//create instance of SLOT local to main
int ret = modifyStruct(&s);pass address of SLOT instance to change member values
printf("Line: %s\n", s.line);//show changed values
printf("Slot: %d\n", s.slot);
printf("type: %s\n", s.type);
printf("position: %s\n", s.position);
return 0;
}
int modifyStruct(SLOT *slot)
{
strcpy(slot->line, "lineA");
slot->slot = 2;
strcpy(slot->type, "large");
slot->position = 20;
return 0;
}
EDIT - To address question in comment asking how to set a struct pointer to point to a struct.
First, it appears from viewing the code you have posted, that you are using self referencing structs. (i.e. a struct that contains a member that is a pointer instance to itself) Here is a link to a good tutorial dealing with Linked Lists in C, which use self referencing structs.
Regarding you comment: _I guess I should have made it more clear. P1_Semaphore is different to semaphore. I need P1_semaphore to point to the semaphore_.:
If P1_Semaphore is different than semaphore, then one should not be set to point to the address of the other. And your compiler will not let you do that anyway.
As I stated in the comments, a struct pointer should only point to a place in memory that contains an instance of that struct. For example consider the two structs A & B:
typedef struct {
int iNum;
float fNum;
char cStr[80];
}A;
A a, *pA; //create an instance, and pointer to an instance of A
typedef struct {
int iNum1;
int iNum2;
int iNum3;
}B;
B b, *pB; //create an instance, and pointer to an instance of B
A & B are obviously different, and will occupy a different size and shape in memory, so if the pointer to B, *pB was set to point to anything but B, it would be incorrect. It needs to point to B
Correct:
pA = &a //set pointer to A equal to the address of A
pB = &b //set pointer to B equal to the address of B
Incorrect:
pA = &b //set pointer to A equal to the address of B
pB = &a //set pointer to B equal to the address of A
(typical compiler error - Operands of = have types pointer to B and pointer to A)
In C/C++, all parameters are passed by value, not by reference. To get the struct pointer in parameter, you need to use pointer to pointer as the parameter. Like this:
int P1_SemCreate(char *name, unsigned int value, P1_Semaphore **sem){
...
*sem = temp;
...
}
Looked through many other SO posts related to this, but none were able to help me. So, I have the following structs defined:
typedef struct
{
int created;
double data;
int timeLeft;
int destination;
}dataPacket;
typedef struct
{
dataPacket *array;
int currIndex;
int firstIndex;
int nextTick;
int maxLength;
int length;
int stime;
int total;
}packetBuffer;
typedef struct{
int mac;
struct wire *lconnection;
struct wire *rconnection;
int numRecieved;
struct packetBuffer *buffer;
int i;
int backoff;
}node;
typedef struct{
float length;
float speed;
int busy;
struct dataPacket *currPacket;
struct node *lnode;
struct node *rnode;
}wire;
And then I'm trying to use the following function:
int sendPacket(node *n, int tick)
{
if(n->buffer->length > 0)
{
if(n->backoff <= 0)
{
if (n->lconnection->busy != 0 || n->lconnection->busy != 0)
{
n->i++;
n->backoff = (512/W * genrand()*(pow(2,n->i)-1))/TICK_LENGTH;
}
else
{
n->lconnection->busy = 1;
n->rconnection->busy = 1;
n->lconnection->currPacket = n->buffer[n->buffer->currIndex];
n->rconnection->currPacket = n->buffer[n->buffer->currIndex];
}
}
else
{
n->backoff--;
}
}
}
I'm getting the error described in the title everytime I try to access a member of buffer, lconnection, or rconnection.
struct packetBuffer *buffer;
You've defined a type packetBuffer (a typedef for an otherwise anonymous struct).
You haven't defined struct packetBuffer.
In the absence of an existing type struct packetBuffer, the compiler treats it as an incomplete type, assuming that you'll complete it later. The declaration
struct packetBuffer *buffer;
is perfectly legal, but you can't dereference buffer unless the type struct packetBuffer is visible.
Just drop the struct keyword.
(My personal preference is to drop the typedef and consistently refer to struct types as struct whatever, but that's a matter of style and taste.)
The following:
typedef struct {
int x;
char *y;
...
} my_struct;
creates an identifier for an anonymous structure. In order, for a structure to refer to an instance of itself, it must not be "anonymous":
typedef struct my_struct {
int x;
char *y;
struct my_struct *link
....
} my_struct_t;
This means that my_struct_t is now the type struct my_struct and not just an anonymous struct. Also, note that struct my_struct can be used within its own structure definition. That is not possible with anonymous structs.
As a final complication, the my_struct in struct my_struct is in a differenct "namespace" than the my_struct_t. This is sometimes used to to simplify (or confuse) things in code like this:
typedef struct my_struct {
int x;
char *y;
struct my_struct *link
....
} my_struct;
Now I can use my_struct anywhere in my code instead of struct my_struct.
Finally, you could separate the typedef from the structure definition to achieve the same effect:
struct my_struct {
int x;
char *y;
struct my_struct *link;
....
};
typedef struct my_struct my_struct;
As noted in David R.Hanson's C Interfaces and Implementations, "This definition is legal because structure, union, and enumeration tags occupy a same name space that is separate from the space for variables, functions, and type names."
struct result {
int number;
int length;
};
struct result findLongestSeq(int intarray[], int size) {
result->number // undefined symbol
}
how to access the struct result inside the function findLongestSeq?
thanks
struct result {
int number;
int length;
};
struct result findLongestSeq(int intarray[], int size) {
struct result result;
result.number = 0;
result.length = 42;
return result;
}
If you are dealing with struct result foo then you access its members via foo.number.
If however you are dealing with a pointer to foo (struct result *foo) then you access its members via foo->number.
If you were to manually allocate your result struct via
struct result *result = (struct result *)malloc(sizeof (struct result));
Then you'd have to access its members via result->number (and would be responsible for freeing it once not used anymore).
Further more I'd rather use this for the sake of better readability:
typedef struct {
int number;
int length;
} ResultStruct;
This way you can then use ResultStruct result; instead of redundant and verbose struct result result;.
You have to keep in mind that by simply typing
struct result {
int number;
int length;
};
you only define how a struct with name result actually looks like, i.e. of what parts it is made up. This is a general definition, but you have variable of that type yet.
To access values of this struct you have to create a variable by
struct result myResult;
or however you want to call it. At this point you are able to access the members of this struct with myResult.number