In this code I am trying to pass a pointer to the structure and then use this pointer to work on the structure members, but why is the output always showing 0?
#include<stdio.h>
#include<string.h>
struct student
{
int go;
} s;
void m();
void main()
{
m(&s);
printf("%d",s.go);
}
void m(struct student *ptr)
{
ptr->go;
}
struct student
{
int go;
}s;
creates a global variable. Global variables are zero initialized unless they are initialized explicitly. That statement is equivalent to:
struct student
{
int go;
};
struct student s = {0};
Hence the value of s.go is 0. The call to m does not change the values of any variables. It has no effect on the output. The output will be 0 even if the call to m(&s) is removed.
The global variable s is initialized with all members 0.
Nothing changes the value of s.go, so the output is 0.
Your question has all sorts of errors, here they are, in no particular order:
you don't need #include <string.h> if you aren't using any "string" functions
you shouldn't use global variables (if you did, it would eliminate the need to pass the pointer to s to functions to access the struct); you should remove the global variable (i.e., make it local) and continue to pass the pointer-to-struct as you are to m() in order to be able to access it outside of main() (where you should declare it)
your signature for main() is incorrect as I pointed out in a comment to OP, and naturally you are missing the return 0; statement in main() because of this
you are missing a newline in your printf()
you aren't actually doing anything with ptr->go in m(); you aren't assigning anything to it or otherwise using it. It is printing zero because, as others have pointed out, global variables (because they are static,) are (default-)initialized
Here is an example with corrections (note you can initialize s as described by others if you wish to use it's value before you modify/set it):
#include <stdio.h>
struct student
{
int go;
};
void m();
int main(void)
{
struct student s;
m(&s);
printf("%d\n", s.go);
return 0;
}
void m(struct student *ptr)
{
ptr->go = 5;
}
When you declare your structure as global , their members are always initialize with its default value, if int than '0' and if char or string than '\0' . So you are getting Value 0.
struct student
{
int go;
} s;
Related
I am working on a problem of running a function through a function pointer, which is a variable of a structure. I tried making a small code but I am not able to build it.
The error I am getting is as below:
Please review the code below. The first statement in the main function is the cause of the error.
I am new to C.Thank you for your kind help.
#include <stdio.h>
#include <stdlib.h>
#include<stdint.h>
typedef int16_t (*reset_start_f)(void); //typedef used for function Pointer
int ThermMgrSvc_Reset(void)
{
int retVal;
retVal=5;
return retVal;
}
typedef struct
{
reset_start_f reset; // function pointer
}module_function_t;
static const module_function_t MODULE_TABLE[]=
{
{(reset_start_f)ThermMgrSvc_Reset},
};
int main()
{
int x2= MODULE_TABLE[0].(*reset)(); // This statement causing Error
printf("x2= %d\n",x2);
return 0;
}
This syntax is invalid:
int x2= MODULE_TABLE[0].(*reset)();
Because the structure access operator . must be followed immediately by the name of the field. The dereferencing operator needs to be before the whole subexpression:
int x2= (*MODULE_TABLE[0].reset)();
Or, since function pointers are dereferenced implicitly when called, you can remove the * entirely:
int x2= MODULE_TABLE[0].reset();
I want to return the name of the smallest city population-wise, if it is the second city. (Please don't mind the if statement, I know it's bland), the missing return is what bothers me.
I assume I should declare a pointer inside the function rSmallestCity, like *rtrn but I guess the source variable is destroyed before it is used?
typedef struct Coordinate{
int x,y;
}Coordinate;
typedef struct city{
char name[20];
int population;
Coordinate coordinates;
}city;
char *rSmallestCity(city **cl, int n)
{
char *rtrn = NULL;
if(cl[n-2]->population>cl[n-1]->population)
{
rtrn = &cl[n-1]->name;
}
return rtrn;
}
int main()
{
city c1 ={.name="Mumbai", .population=310, .coordinates.x=3, .coordinates.y=4};
city c2 ={.name="Delhi", .population=300, .coordinates.x=3, .coordinates.y=2};
city *clist[2];
clist[0]=&c1;
clist[1]=&c2;
printf("\n%s is smallest\n",rSmallestCity(clist,2));
}
warning: assignment to 'char ' from incompatible pointer type 'char ()[20]' [-Wincompatible-pointer-types]|
I assume I should declare a pointer inside the function rSmallestCity, like *rtrn but I guess the source variable is destroyed before it is used?
A good question. And your assumption is correct. Creating a variable inside a function it's existence ends upon leaving the function. But in this case, because the struct member name is already a char * you do not need to create another variable. Just return c1.name. (see code example below.)
A few other suggestions:
In the struct declaration:
typedef struct Coordinate{
int x,y;
}Coordinate;
You've used the same symbol (Coordinate) for the struct name, and for it's typedef. This is not a good practice. If you need both a struct name and a typedef, pick different symbols. BTW, in this this example, only one or the other is needed. Say you pick the typedef, then the struct is completely defined by:
typedef struct {
int x,y;
}Coordinate;
That suggestion applies to both struct declarations in your example code.
The signatures for the main function do not include int main(){...} rather
int main(void){..., return 0;} and int main(int argc, char *argv[]){..., return 0;}
The following code example illustrates some of the other suggestions for improvements in comments under your post,
typedef struct {
int x,y;
}Coordinate;
typedef struct {
char name[20];
int population;
Coordinate coordinates;
}city;
//return char * rather than char to allow for full null terminated char array (string)
char * rSmallestCity(city c1[],int cityCount)//generisize function prototype to
{ //to easily accommodate bigger arrays if needed
long long size, sizeKeep = 8e9; //index and population. initialize larger than possible population
int indexKeep = 0;
//note you do not need to define a char *, the struct already contains one
for(int i=0; i<cityCount; i++)//use a loop rather than a single comparison, keep the smalles
{
size = c1[i].population;
sizeKeep = (size < sizeKeep) ? indexKeep = i, size : sizeKeep;
}
printf("\n%s\n",c1[indexKeep].name);
return c1[indexKeep].name;
};
int main(void)//use minimum signature for main, and call return before leaving.
{
//combining your original declarations and assignments for struct
//into a single declaration/definition.
city c1[] = {{.name="Mumbai", .population=310, .coordinates.x=3, .coordinates.y=4},
{.name="Delhi", .population=300, .coordinates.x=3, .coordinates.y=2}};
int cityCount = sizeof(c1)/sizeof(c1[0]);
printf("\n%s is smallest",rSmallestCity(c1, cityCount));
return 0;
};
The solution that I originally left in comment under OP (remove & in the line &cl[n-1]->name;) needs some explanations to avoid problems later.
(It is an educational answer not a full answer on pointers, array decay, ... And many examples can be found on stackoverflow. I tried to simplify)
Try this simple code.
int main()
{
char myString1[25]="Toulouse" ; // French City
printf("%p\n",myString1);
printf("%p\n",&myString1);
}
The output is the same, but an array name and the address of an array name are not the same. The array name is evaluated to the address of its first element. So it works in your case but a warning is issued during compilation and it is very important. Firstly, do not remove compilation warnings.
Now, try this code :
int main()
{
char myString1[25]="Toulouse" ; // French City
printf("%p\n",myString1+1);
printf("%p\n",&myString1+1);
}
The outputs are different. Because myString1 is evaluated to char* and &myString1 to char [25]. So +1, in the first, case adds one (sizeof char) to the pointer and in the other case, it adds 25.
Delete the "&" in the line:
rtrn = &cl[n-1]->name;
To extremely simplify, you assigned an "address of char[]" to a char*, but array syntax makes it work regardless.
As shown in this small script.
#include <stdio.h>
struct student{
short count;
void (*addCount)();
};
void student_addCount(struct student a){
a.count++;
}
int main(){
struct student student;
student.addCount = student_addCount;
student.count = 0;
student.addCount();
student.addCount();
student.addCount();
student.addCount();
student.addCount();
printf("%d\n",student.count);
}
I have added a pointer to a function inside a struct, but I do not know why this works as the function 'addCount' is not receiving any arguments and it actually adds up the number of times specified.
I am compiling this code with GCC 6.3.0 in different environments such as ideone.com, wandbox.org and the compiler in WSL.
here is the proof that it works with ideone.
https://ideone.com/Cam4xY
That's not a function inside a structure, it's a function pointer inside a structure.
void (*addCount)();
defines addCount as a pointer to a function. The function returns void and takes an unspecified number of arguments.
That's what the empty parentheses mean. That's an old-style non-prototype function declaration. There is rarely, if ever, a good reason to use non-prototype function declarations or definitions. If you want to specify tht a function takes no arguments, use (void) rather than ().
student.addCount = student_addCount;
The function student_addCount takes a struct student argument, but its type is still compatible with the type of your pointer member. Assigning it like this essentially disables checking on calls. This is why old-style function declarations are a bad idea.
student.addCount();
This is an indirect call via the function pointer. Since the function pointer type doesn't specify how many arguments are expected, the call is legal. Since the actual function being called requires a single argument of type struct student, the behavior is undefined. With old-style function declarations, it's entirely up to you, the programmer, to get the arguments right; the compiler won't help you.
Since you're getting what appear to be valid results, it's likely that the argument you expected to be passed happened to be in the right place in memory, perhaps on top of the stack. The function is called and it assumes, quite reasonably, that you've passed a proper argument value. It looks for that argument in memory, or in a register, and finds ... something.
Here's a version of your program without the undefined behavior:
#include <stdio.h>
struct student{
short count;
void (*addCount)(struct student a);
};
void student_addCount(struct student a){
a.count++;
}
int main(void){
struct student student;
student.addCount = student_addCount;
student.count = 0;
student.addCount(student);
student.addCount(student);
student.addCount(student);
student.addCount(student);
student.addCount(student);
printf("%d\n",student.count);
}
The output is 0 -- because the count being incremented is a member of the parameter, which is a local object.
Here's a version that does what you probably want. It passes a pointer to the structure, so the count member of your original struct student object is incremented by the function. The output is 5.
#include <stdio.h>
struct student{
short count;
void (*addCount)(struct student *a);
};
void student_addCount(struct student *a){
a->count++;
}
int main(void){
struct student student;
student.addCount = student_addCount;
student.count = 0;
student.addCount(&student);
student.addCount(&student);
student.addCount(&student);
student.addCount(&student);
student.addCount(&student);
printf("%d\n",student.count);
}
I got a question regarding to static member of structure
Here is the scenario:
Need 2d array variable to retain its values even after exited from the function in another C files. Subsequent call from main()-in another C file, to the function will use that last value and continue to do calculation to produce and update new values(retained also). So, I I think I need to use static for that array.
The 2D array is member of an 2D structure. I need 2D structure for identity purposes for the 2d array. Lets say I got identity[row][column] with member[5][5], I need statically define the member throughout the call from main(). But static for structure member is not allowed in C as I notice.
code i am trying on:
//in function.h
#define row 2
#define column 5
int function(int rowNUM);
//in function.c
int function(int rowNUM)
{
typedef struct {
static int member[5][5];
int y[5][5];
int forg;
} mystruct;
mystruct identity[row][column];// declare the identity as structure array
int columnNUM;
int c;
int d;
//----try to initialize member to 1
for (columnNUM=0;columnNUM<column;columnNUM++)
{
for (c=0;c<5;c++)
{
for(d=0;d<5;d++){
identity[rowNUM][columnNUM].member[c][d]=1;
}
}
}
//----try to update member--- The values should retain for subsequent call from main
for (columnNUM=0;columnNUM<column;columnNUM++)
{
for (c=0;c<5;c++)
{
for(d=0;d<5;d++){
identity[rowNUM][columnNUM].member[c][d]=1+identity[rowNUM][columnNUM].member[c][d]; // to update member new value
}
}
}
}
// in main.c
main()
{
function(1);
function(2);// member here is in different identity from function (1)
function(1);//member should retain its value from function(1)
function(2);//member should retain its value from function(2)
}
Any other suggestion is welcomed if this is not the way to achieve the goal.
I am quite new in programing Please help me on this.
You have defined a 2d array of structs, which is really hard to statically initialize because each struct contains matrices of ints. Also, you can't have only a member of a struct static, the whole structure has to be defined static.
The easiest way I can think of doing what you want is defining an static matrix of mystructs and a helper variable to initialize it just on the first call, ie,
//in function.c
#include <stdbool.h>
int function(int rowNUM)
{
typedef struct {
int member[5][5];
int y[5][5];
int forg;
} mystruct;
// helper flag
static bool first_call = true;
// this is a matrix of (row x cols) mystructs
static mystruct identity[row][col];
if (first_call) {
/* initialize the matrix however you want
BUT remember to set first_call to false!
*/
first_call = false;
}
// rest of function ...
}
If you don't want to keep the values of the y and forg members (what does forg stand for? is it a typo?), you should split the struct in two, but I can't see why would you want to keep some values of the struct and discard others unless they are temporal variables.
If y and forg are temporal varaibles, you should definitely split your struct definition in two.
Another way of doing that is passing the pointer to the matrix as a parameter to your function, so you can maintain state without using a static variable
int function(int rowNUM, mystruct **identity)
But note that, although most of the times arrays decay to pointers (you can find more information in similar questions to this one), they are not the same thing.
If you only want a member of the struct to be static, your best option will be to make a static type in the function, which in your case would be a static 2D array, and do the assignment to the [stack] structure when the function is called.
Eg:
.. function(...)
{
static int b[2][2]
typedef struct { int a[2][2] } struct1;
struct1 x[2][2];
x->a = b;
}
void function(int rowNUM){
int c;
int d;
int columnNUM;
typedef struct {
int member[3][3];
}mystruct;
mystruct identity[ROW][COLUMN];
static bool first_call = true;
if (first_call) {
// INTIALIZE each element of member array to 1
for (columnNUM=0;columnNUM<COLUMN;columnNUM++)//total cell
{
for (c=0;c<3;c++)
{
for(d=0;d<3;d++){
identity[rowNUM][columnNUM].member[c][d]=1;
//printf("identity[%d][%d].member[%d][%d]=%d\n",rowNUM,columnNUM,c,d,identity[rowNUM][columnNUM].member[c][d]);
}
}
}
first_call = false;
}
identity[0][0].member[0][0]=identity[0][0].member[0][0]+3;
printf("%d\n", identity[0][0].member[0][0]);
identity[0][0].member[0][1]=identity[0][0].member[0][1]+1;
printf("%d\n", identity[0][0].member[0][1]);
}
The above code produce:
first call= 4 2 second call= 7 3 third call= 10 4
Work perfectly fine,nice. But it works fine either I declare
mystruct identity[ROW][COLUMN];
or
static mystruct identity[ROW][COLUMN];
Does it mean I dont need to declare static at all?
Here is part of my code. I would like to initialize only the arraylist[0] as arraylist[0].x = 0 and arraylist[0].y = 0. I do not need to initialize the rest of the struct array. How can I do it? Thank you.
#include <stdio.h>
struct example {
int x;
int y;
};
struct example arraylist[40];
int main(int argc, char *argv[]){
printf("%d\n %d\n", arraylist[0].x, arraylist[0].y);
return 0;
}
You can initialise any particular element of the struct array.
For example:
struct example arraylist[40] = { [0]={0,0}}; //sets 0th element of struct
struct example arraylist[40] = { [5]={0,0}}; //sets 6th element of struct
This is called Designated Initializers which used to be a GNU extension before C99 adapted it and is also supported in standard C since C99.
Since you are talking about a variable in file scope, here, you don't have to do anything, since such variables are always initialized by 0 if you don't provide an explicit initializer.
In C, once you initialize part of a struct / array, you initialize the rest of it with 0.
You should have no problem with that, as you should not access uninitialized variables in first place, and their value is not defined.
In C all static and extern variables are initialized to 0 unless explicitly initialized otherwise.