Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am having problem with the bolded variables. CLion said that those parameters are never accessed.
When I call the function open_turn, the turn_face, and turn_suit are said that they have not been initialized. But I do not want to initialize those variables by assigning values to them since the values are only determined after the function is called.
How do I pass int turn_card, int turn_f, and int turn_s into the function open_turn? Then assigning value of int turn_card to int turn, int turn_f to int turn_face, and int turn_s to turn_suit?
P/s: At this moment, parameters int turn_f and int turn_s are said to be declared but never accessed.
void open_turn(int current_deck[], int turn_card, int turn_f, int turn_s);
int main() {
int turn;
int turn_face;
int turn_suit;
open_turn(deck, turn, turn_face, turn_suit);
}
void open_turn(int current_deck[], int turn_card, int turn_f, int turn_s) {
turn_card = current_deck[card_idx++];
turn_f = turn_card%13;
turn_s = turn_card/13;
You're doing this all wrong. In c, when you pass an argument to a function, you end up passing a copy of the the variable by value. Modifying the variable in the function has no (useful) impact, since you're just modifying a temporary copy of the variable which is discarded when the function call finishes. The compiler is right to barf out errors for this. To accomplish what you likely intend to do, you need to use pointers, and you still need to initialize them.
Note that you likely still have errors in your code since you haven't shown us how current_deck is defined.
Code Listing
/*******************************************************************************
* Preprocessor directives.
******************************************************************************/
#include <stdio.h>
/*******************************************************************************
* Function prototypes.
******************************************************************************/
void open_turn(int current_deck[], int turn_card, int turn_f, int turn_s);
/*******************************************************************************
* Function definitions.
******************************************************************************/
int main(void)
{
int turn;
int turn_face;
int turn_suit;
open_turn(deck, &turn, &turn_face, &turn_suit);
/* The following also works. */
int* pTurn = &turn;
int* pTurn_face = &turn_face;
int* pTurn_suit = & turn_suit;
open_turn(deck, pTurn, pTurn_face, pTurn_suit);
}
void open_turn(int current_deck[], int* turn_card, int* turn_f, int* turn_s)
{
if ( !turn_card || !turn_f || !turn_s )
{
printf("Invalid input.\n");
return;
}
*turn_card = current_deck[card_idx++];
*turn_f = turn_card%13;
*turn_s = turn_card/13;
}
If you want to return back a value from a function in C you must pass a pointer to the variable. For example:
#include <stdio.h>
void f( int x, int *p) {
x = 0; /* This only affects local param x */
*p = 5; /* copies x's value into variable pointed to by p */
}
int main() {
int a = 1, b = 2;
f(a, &b); /* a passed by value, b's address is passed */
printf("a = %d, b= %d\n", a, b); /* prints out a = 1, b = 5 */
}
Here the compiler might warn that the x variable in function f is assigned a value that is not accessed, since setting it to 0 had no affect on a in main. *p = 5 did not create a warning because it is affecting b's value which is then used in the printf call.
Related
This question already has an answer here:
note: previous implicit declaration of ‘point_forward’ was here
(1 answer)
Closed 1 year ago.
In an effort to learn C and string operations, I'm making a small program that simply generates random IP addresses as strings and outputs it. From what I've gathered from various tutorials as well as examples here on stackoverflow, the below would be one way of doing so, but returning the character array reference is what stumps me, as it doesn't compile:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *testip = randip();
printf("%s", testip);
free(testip);
return 0;
}
// get rand IP
char* randip()
{
char *ip = malloc(16);
int a = randint(1,254);
int b = randint(0,254);
int c = randint(0,254);
int d = randint(0,254);
sprintf(ip, "%d.%d.%d.%d", a, b, c, d);
printf("D> randip generated %s", ip);
return ip;
}
// generate rand int
int randint(unsigned int min, unsigned int max)
{
double scaled = (double)rand()/RAND_MAX;
return (max - min +1)*scaled + min;
}
gcc output:
test.c: In function ‘main’:
test.c:8:18: warning: initialization makes pointer from integer without a cast [enabled by default]
test.c: At top level:
test.c:17:7: error: conflicting types for ‘randip’
test.c:8:18: note: previous implicit declaration of ‘randip’ was here
I am unable to see which types are incompatible? Did I accidentally return, call, or miscast a type I didn't intend for?
Note: Yes, I know my randomness isn't very random, and there are probably better way of handling that part, but that's outside of the scope of this question.
You need the function prototype before it is called.
If the function does not take parameters declare it as char* randip(void)
Use the correct main signature. In this case int main(void)
int randint(unsigned int min, unsigned int max);
char* randip(void);
int main(void)
{
/* ...*/
}
char* randip(void)
{
/* ...*/
}
// generate rand int
int randint(unsigned int min, unsigned int max)
{
/* ...*/
}
I am getting all Zeroes in global_array_of_file2.Idea is to get the updated values from file1.c
========================file1.c===========================
#include <stdio.h>
#include <string.h>
int global_array_of_file1[10];
void func1(int a1,int b)
{
int array1_of_func1[10] = {0};
int a;
array1_of_func1[5] = 23;
array1_of_func1[6] = 34;
memcpy(global_array_of_file1,array1_of_func1,10*sizeof(int));
for (a = 0; a < 9; a++)
{
printf("from func_1 : global_array = %d \n " , global_array_of_file1[a]);
}
}
void init_pointer(int *tmp)
{
tmp = global_array_of_file1;
}
~
==========================file2.c======================
#include<stdio.h>
#include "file1.h"
int global_array_of_file2[10] = {0};
int main()
{
int i;
init_pointer(global_array_of_file2);
func1(3,4);
for(i = 0; i < 9 ; i++)
{
printf("global_array_of_file2 = %d \n" , global_array_of_file2[i]);
}
return 0;
}
========================file1.h===========================
void init_pointer(int *tmp);
void func1(int a,int b);
There are two issues here:
First issue is:
the code for init_pointer does nothing:
void init_pointer(int *tmp)
{
tmp = global_array_of_file1;
}
as tmp variable is a copy of the input variable (called by value), it does nothing.
To have it work correctly it should be something like this:
void init_pointer(int **tmp)
{
*tmp = global_array_of_file1;
}
However, as the global_array_of_file2 is declared as array, it is actually a static pointer which cannot be changed, so you cannot modify its value using statement like **tmp= global_array_of_file1.
Therefor to make it work, you should call memcpy within the init pointer method:
like this:
void init_pointer(int *tmp)
{
memcpy( tmp, global_array_of_file1, 10 * sizeof(int) );
}
The second issue, is that the code at main, first call the init_pointer (which does nothing), then it calls 'func1' which initialize the array. the order shall be the opposite. first call func1 to set the array with the appropriate values, then call the init_array method to copy this information to global array 2.
so instead of
init_pointer(global_array_of_file2);
func1(3,4);
it shall be
func1(3,4);
init_pointer(global_array_of_file2);
This is all if you want to have a copy of the global_array_file1 at file2.
If you want, you can have the same array shared between files, to do so:
at file1.h declare the array as extern:
extern int global_array_of_file1[10];
Then you can simply use it at file2.c which include file1.h
Ok I think this can be fixed easily by doing the below :
declare extern int global_array_of_file1[10] in file1.c
define int global_array_of_file1[10] = {0}; in file2.c
I then dont even need to initialize the pointer from file2.c ( no need to call init_pointer) and extra RAM too will be saved :) !
The memcpy is wrong. You just copy 10 bytes.
An int is usually 4 Bytes long (32 bit), thus you only copy parts of the array, namely the first ten bytes, thus you copy just the ints with index 0,1,2 and half of 4.
You need to copy 10 * sizeof(int)
I'm trying to make a program that for a given int value keeps the amount of dividers:
int amount_of_dividers and a list of those dividers: int* dividers
This is the code:
#include <stdio.h>
#include <stdlib.h>
typedef struct{
int value;
int amount;
int* dividers;
} Divide;
int main(){
Divide ** tt;
read_dividers(tt,5);
}
/* the functions "amount_of_dividers(int g)" and "dividers_of(int g, int amount)"
used in void read_divider are working properly, they are not needed for this question */
void read_divider(Divide *g){
scanf("%d",&(g->value));
g->amount = amount_of_dividers(g->value);
g->dividers = dividers_of(g->value,g->amount);
}
/* assuming that read_divider works, what causes read_dividerS to crash? */
void read_dividers(Divide ** t, int amount){
int i = 0;
t = malloc(amount*sizeof(Divide*));
for(i = 0;i<amount;i++){
read_divider(t[i]);
}
}
Read_dividers uses an array of pointers **t where i'm trying to fill each element of this array with a pointer to a Divide g variable.
EDIT: input in this case in main() : "read_dividers(tt,5)" means the user gives 5 int's, which get converted to 5 Divide structs.
What happens instead is the program crashes after I give in the second int
If any more information is missing, don't hesitate to ask!
You are passing an uninitialized t[i] to read_divider. t is supposed to be pointer to pointer to Divide, not pointer to Divide, you may have just got lucky on your first pass, but I suspect it failed on the very first call.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
"While passing global variable in function parameter, is it passed by reference or value ?"
It is passed by value. The following code shows that this is the case:
#include <stdio.h>
int global = 5;
void foo(int bar){
bar = 6;
printf("bar = %d\nglobal = %d", bar, global);
}
int main(){
foo(global);
return 0;
}
The output is:
bar = 6
global = 5
In this code global was passed as a parameter for foo, we called this parameter bar. So at the beginning global and bar are two different variables both having the value 5. But then bar is assigned the value 6 and since the argument was referenced by value, global stays at 5.
To pass the variable by reference, use pointers:
#include <stdio.h>
int global = 5;
void foo(int *bar){
*bar = 6;
printf("bar = %d\nglobal = %d", *bar, global);
}
int main(){
foo(&global);
return 0;
}
Now the output is:
bar = 6
global = 6
Both local and global variables are passed to functions by value in C. If you need to pass by reference, you will need to use pointers.
How the variable is/must be passed, depends on the function, not on the variable:
int gMyVar;
void foo(int a); // says "call me by value"
void bar(int *b); // says "call my by reference"
foo requires an int to be passed. you must call it as foo(gMyVar).
bar requires a pointer to an int. You must call it as bar(&gMyVar).
So, as other answers indicated, C always passes a value, however, the value can be the value of a variable (call by value) or can be a pointer to a variable (call by reference).
First of all, Why do we need to pass Global variable in a function? we can directly access it any where in the program if you dont know.
#include <stdio.h>
int x = 10; //global variable
void fun()
{
printf("%d",x); // direct access
}
int main(void) {
fun(); // no argument required
return 0;
}
Output
10
For demo http://ideone.com/VLWqNO
I have a struct with a pointer component. The pointer will point to an array whose size will be determined after the struct is declared. I will need to malloc memory and then assign it to the pointer. Somehow passing this pointer through function calls causes problems. Here is a simple example which recreates my error:
#include <stdlib.h>
#include <stdio.h>
typedef struct mystruct mystruct;
struct mystruct{
int dim;
double *dubarr;
double dub;
};
int getarr(int *dim, double *dubarr){
*dim = 2; /* The value of dim is not known until this function is called */
dubarr = malloc(*dim * sizeof(double));
double test;
int i;
for(i=0;i<*dim;i++)
{
dubarr[i] = (i+1)*7.0;
test = dubarr[i];
printf("dubarr[%i] = %.15e\n", i, test);
}
return 1;}
int initmystruct(mystruct *data){
getarr(&(data->dim),data->dubarr);
data->dub = (data->dim)*((data->dubarr)[0]);
return 1;}
int main(void){
mystruct data;
initmystruct(&data);
double test;
int i;
for(i=0;i<data.dim;i++)
{
test = (data.dubarr)[i];
printf("dubarr[%i] = %.15e\n", i, test);
}
/* I would do "free(data.dubarr);" here but it causes a crash */
return 1;}
The code compiles with no warnings but the components of data.dubarr do not maintain their values through the function calls. Here is the output:
dubarr[0] = 7.000000000000000e+00
dubarr[1] = 1.400000000000000e+01
dubarr[0] = 2.002400628035951e+176
dubarr[1] = 2.186218092030684e-154
Please point out all my mistakes :)
C uses pass by value. So here:
int getarr(int *dim, double *dubarr)
the function receives dubarr, a pointer to double, passed by value. So, whatever the function assigns to dubarr cannot be seen outside getarr. Note that the implementation of getarr modifies dubarr, but the caller will not see those modifications.
Contrast that with how you handle dim, where you modify *dim. Similarly look at the call to getarr in your code:
getarr(&(data->dim), data->dubarr);
Observe how the two arguments are treated differently. For the first argument you pass the address of a variable, for the second you pass the value of the pointer.
Instead you need:
int getarr(int *dim, double **dubarr)
And then assign to *dubarr like this:
*dubarr = malloc(...);
And call getarr like this:
getarr(&(data->dim), &(data->dubarr));