I am shifting from Python to C so bit rusty on the semantics as well as coding habit. In Python everything is treated as an object and objects are passed to functions. This is not the case in C so I want to increment an integer using pointers. What is the correct assignment to do so. I want to do it the following way but have the assignments wrong:
#include <stdio.h>
int i = 24;
int increment(*i){
*i++;
return i;
}
int main() {
increment(&i);
printf("i = %d, i);
return 0;
}
I fixed your program:
#include <stdio.h>
int i = 24;
// changed from i to j in order to avoid confusion.
// note you could declare the return type as void instead
int increment(int *j){
(*j)++;
return *j;
}
int main() {
increment(&i);
printf("i = %d", i);
return 0;
}
Your main error was the missing int in the function's argument (also a missing " in the printf).
Also I would prefer using parentheses in expressions as *j++ and specify exactly the precedence like I did in (*j)++, because I want to increment the content of the variable in the 'j' location not to increment the pointer - meaning to point it on the next memory cell - and then use its content.
Related
In the below code scanf() is working for getting the name from the user but fgets() is not working pls someone help me to understand why it's not working
#include <stdio.h>
#include <stdlib.h>
typedef struct university{
int roll_no;
char name[16];
}uni;
int main()
{
uni *ptr[5],soome;char i,j=0;
for(i=0;i<5;i++)
{
ptr[i]=(uni*)calloc(1,20);
if(ptr[i]==NULL)
{
printf("memory allocation failure");
}
printf("enter the roll no and name \n");
printf("ur going to enter at the address%u \n",ptr[i]);
scanf("%d",&ptr[i]->roll_no);
//scanf("%s",&ptr[i]->name);
fgets(&ptr[i]->name,16,stdin);
}
while(*(ptr+j))
{
printf("%d %s\n",ptr[j]->roll_no,ptr[j]->name);
j++;
}
return 0;
}
First of all, fgets(char *s, int n, FILE *stream) takes three argument: a pointer s to the beginning of a character array, a count n, and an input stream.
In the original application you used the address operator & to get the pointer not to the first element of the name[16] array, but to something else (to use the address operator, you should have referenced the first char in the array: name[0]).
You use a lot of magic numbers in your application (e.g. 20 as the size of the uni struct). In my sample I'm using sizeof as much as possible.
Given that you use calloc, I've used the fact that the first parameter is the number of elements of size equal to the second parameter to preallocate all the five uni struct at once.
Final result is:
#include <stdio.h>
#include <stdlib.h>
#define NUM_ITEMS (5)
#define NAME_LENGTH (16)
typedef struct university{
int roll_no;
char name[NAME_LENGTH];
} uni;
int main()
{
uni *ptr;
int i;
ptr = (uni*)calloc(NUM_ITEMS, sizeof(uni));
if(NULL == ptr) {
printf("memory allocation failure");
return -1;
}
for(i=0; i<NUM_ITEMS; i++) {
printf("enter the roll no and name \n");
printf("You're going to enter at the address: 0x%X \n",(unsigned int)&ptr[i]);
scanf("%d",&ptr[i].roll_no);
fgets(ptr[i].name, NAME_LENGTH, stdin);
}
for(i=0; i<NUM_ITEMS; i++) {
printf("%d - %s",ptr[i].roll_no,ptr[i].name);
}
free(ptr);
return 0;
}
Note: I've added a call to free(ptr); to free the memory allocated by calloc at the end of the application and a different return code if it's not possible to allocate the memory.
I am trying to keep track of a set of data by declaring a class.
The class is initialized with a unique ID but then fills the rest of the variables out later in the code after some calculations.
First, is that even an acceptable way to do this?
Second, I'm trying to pass it a char array but it does not want to take the value. Is this the correct way to define the fileName and call it back when creating the file?
Here's the example, I define a variable from the Customer class then try to store its filename:
#ifndef customer_h
#define customer_h
class Customer
{
public:
Customer (char *number);
char *ID;
double current;
double voltage;
double powerConsumption;
double remainingCredit;
int relay;
char *lastName;
char *firstName;
char *fileName;
private:
};
Customer::Customer(char *number)
{
ID = number;
}
#endif
void setup()
{
cust1.fileName = getFileName(cust1.ID);
}
char *getFileName(char *customerID)
{
char *charID;
String newID;
for (int i = strlen(customerID)-4; i<= strlen(customerID)-1; i++)
{
newID += customerID[i];
}
newID += ".csv";
int lenID = newID.length() + 1;
char fileName[lenID];
newID.toCharArray(fileName,lenID);
return fileName;
}
Thanks a lot in advance for any help and info you can provide!
Be better to use a structured rather than a class. They are pretty similar but in this case seems like a structure will be much better go and read about the differences and you'll see
I am sorry that I cannot support my question with some code (I didnt understand how to structure it so it would be accepted here), but I try anyway.
If I understand correctly, a struct that references a struct of same type would need to do this with contained pointer for reference. Can this pointer reference to allocated space on the stack (instead of the heap) without creating segmentation fault? -
how should this be declared?
Yes, you can use pointers to variables on the stack, but only when the method that provides that stack frame has not returned. For example this will work:
typedef struct
{
int a;
float b;
} s;
void printStruct(const s *s)
{
printf("a=%d, b=%f\n", s->a, s->b);
}
void test()
{
s s;
s.a = 12;
s.b = 34.5f;
printStruct(&s);
}
This will cause an error however, as the stack frame would have disappeared:
s *bad()
{
s s;
s.a = 12;
s.b = 34.5f;
return &s;
}
EDIT: Well I say it will cause an error, but while calling that code with:
int main()
{
test();
s *s = bad();
printStruct(s);
return 0;
}
I get a warning during compilation:
s.c:27:5: warning: function returns address of local variable [enabled by default]
and the program appears to work fine:
$ ./s
a=12, b=34.500000
a=12, b=34.500000
But it is, in fact, broken.
You didn't say what language you are working in, so assuming C for now from the wording of your question... the following code is perfectly valid:
typedef struct str_t_tag {
int foo;
int bar;
struct str_t_tag *pNext;
} str_t;
str_t str1;
str_t str2;
str1.pNext = &str2;
In this example both str1 and str2 are on the stack, but this would also work if either or both were on the heap. The only thing you need to be careful of is that stack variables will be zapped when they go out of scope, so if you had dynamically allocated str1 and passed it back out of a function, you would not want str1->pNext to point to something that was on the stack within that function.
In other words, DON'T DO THIS:
typedef struct str_t_tag {
int foo;
int bar;
struct str_t_tag *pNext;
} str_t;
str_t *func(void)
{
str_t *pStr1 = malloc(sizeof(*pStr1));
str_t str2;
pStr1->pNext = &str2;
return pStr1; /* NO!! pStr1->pNext will point to invalid memory after this */
}
Not sure if this is specifically a C/C++ question, but I'll give C/C++ code as example in anyway.
The only way you can declare it: (with minor variations)
typedef struct abc
{
struct abc *other;
} abc;
other can point to an object on the stack as follows:
abc a, b; // stack objects
b.other = &a;
This is not a question about scope, so I'll skip commenting on possible issues with doing the above.
If, however, you want to assign it to a dynamically created object, there's no way this object can be on the stack.
abc b;
b.other = malloc(sizeof(abc)); // on the heap
I cannot get this code to work properly. When I try to compile it, one of three things will happen: Either I'll get no errors, but when I run the program, it immediately locks up; or it'll compile fine, but says 'Segmentation fault' and exits when I run it; or it gives warnings when compiled:
"conflicting types for ‘addObjToTree’
previous implicit declaration of ‘addObjToTree’ was here"
but then says 'Segmentation fault' and exits when I try to run it.
I'm on Mac OS X 10.6 using gcc.
game-obj.h:
typedef struct itemPos {
float x;
float y;
} itemPos;
typedef struct gameObject {
itemPos loc;
int uid;
int kind;
int isEmpty;
...
} gameObject;
internal-routines.h:
void addObjToTree (gameObject *targetObj, gameObject *destTree[]) {
int i = 0;
int stop = 1;
while (stop) {
if ((*destTree[i]).isEmpty == 0)
i++;
else if ((*destTree[i]).isEmpty == 1)
stop = 0;
else
;/*ERROR*/
}
if (stop == 0) {
destTree[i] = targetObj;
}
else
{
;/*ERROR*/
}
}
/**/
void initFS_LA (gameObject *target, gameObject *tree[], itemPos destination) {
addObjToTree(target, tree);
(*target).uid = 12981;
(*target).kind = 101;
(*target).isEmpty = 0;
(*target).maxHealth = 100;
(*target).absMaxHealth = 200;
(*target).curHealth = 100;
(*target).skill = 1;
(*target).isSolid = 1;
(*target).factionID = 555;
(*target).loc.x = destination.x;
(*target).loc.y = destination.y;
}
main.c:
#include "game-obj.h"
#include "internal-routines.h"
#include <stdio.h>
int main()
{
gameObject abc;
gameObject jkl;
abc.kind = 101;
abc.uid = 1000;
itemPos aloc;
aloc.x = 10;
aloc.y = 15;
gameObject *masterTree[3];
masterTree[0] = &(abc);
initFS_LA(&jkl, masterTree, aloc);
printf("%d\n",jkl.factionID);
return 0;
}
I don't understand why it doesn't work. I just want addObjToTree(...) to add a pointer to a gameObject in the next free space of masterTree, which is an array of pointers to gameObject structures. even weirder, if I remove the line addObjToTree(target, tree); from initFS_LA(...) it works perfectly. I've already created a function that searches masterTree by uid and that also works fine, even if I initialize a new gameObject with initFS_LA(...) (without the addObjToTree line.) I've tried rearranging the functions within the header file, putting them into separate header files, prototyping them, rearranging the order of #includes, explicitly creating a pointer variable instead of using &jkl, but absolutely nothing works. Any ideas? I appreciate any help
If I see this correctly, then you don't initialize elements 1 and 2 of the masterTree array anywhere. Then, your addObjToTree() function searches the - uninitialized - array for a free element.
Declaring a variable like gameObject *masterTree[3]; in C does not zero-initialize the array. Add some memset (masterTree, 0, sizeof (masterTree)); to initialize.
Note that you're declaring an array of pointers to structs here, not an array of structs (see also here), so you also need to adjust your addObjToTree() to check for a NULL-pointer instead of isEmpty.
It would also be good practice to pass the length of that array to that function to avoid buffer overruns.
If you want an array of structs, then you need to declare it as gameObject masterTree[3]; and the parameter in your addObjToTree() becomes gameObject *tree.
This code:
#include <stdlib.h>
#include <stdio.h>
int j_btree_create (int fn_initial_nodes);
typedef struct {
int depth;
int value;
void *item;
void *left_pointer;
void *right_pointer;
} j_btree_node_int;
typedef struct {
int nodes;
int available_nodes;
int btree_extension;
} j_btree_descriptor_int;
int j_btree_create (int fn_initial_nodes) {
int *free_btree_node;
int loop_counter;
j_btree_descriptor_int *btree_start;
btree_start = (j_btree_descriptor_int *) malloc (((sizeof(j_btree_node_int) + sizeof(free_btree_node)) * fn_initial_nodes) + sizeof(j_btree_descriptor_int));
printf ("btree_start: " . btree_start);
/* *btree_start.nodes = fn_initial_nodes;
*btree_start.available_nodes = fn_initial_nodes;
*btree_start.extension = NULL; */
for (loop_counter = 0; loop_counter < fn_initial_nodes; loop_counter++) {
printf ("loop_test:" . loop_counter);
}
}
Produces this error:
/home/jamie/aws/btree_int.c||In function ‘j_btree_create’:|
/home/jamie/aws/btree_int.c|28|error: request for member ‘btree_start’ in something not a structure or union|
/home/jamie/aws/btree_int.c|33|error: request for member ‘loop_counter’ in something not a structure or union|
||=== Build finished: 2 errors, 0 warnings ===|
When compiled with CodeBlocks. I have not managed to find an exact answer to my problem (I have looked), does anyone know roughly what I am doing wrong? Probably more than one thing given I am fairly new to C.
printf ("btree_start: " . btree_start);
This is not how the things are done in c. There's no . concatenation operator and you do not concatenate strings (pointers to characters) and pointers to structures. If you want to print out the pointer, it's
printf("btree_start: %p\n",btree_start);
For the loop counter it's
printf("loop_test: %d",loop_counter);