I am having trouble getting the ROBX and ROBY variables to print in the main function. This is a small portion of my program and I do not know what I am doing wrong. Thanks!
#include <stdio.h>
#include <time.h>
#define ROW 8
#define COLUMN 8
int robot (int m[ROW][COLUMN], int ROBX, int ROBY);
int ROBX;
int ROBY;
int main(void)
{
printf("%d %d\n", ROBX, ROBY);
return 0;
}
int robot (int m[ROW][COLUMN], int ROBX, int ROBY)
{
// ensure different output each time program is run
srand ( time(NULL) );
// Pick a random spot to place the robot
int placed = 0;
int ROBX;
int ROBY;
while(placed == 0)
{
int t = rand() % ROW;
int y = rand() % COLUMN;
if(m[t][y] == 0)
{
m[t][y] = -2;
placed = 1;
ROBX = t;
ROBY = y;
}
return ROBX, ROBY;
}
}
There are several problems with your code.
For one thing, you never call robot, so none of those modifications to your variables are happening.
For another, you're not allowed to return multiple values from a function: The line return ROBX, ROBY; is NOT doing what you think it's doing.
Finally, your function doesn't make a lot of sense. You intend to pass in ROBX and ROBY as parameters. That won't work the way you think it will, but it's not a terrible idea in general. But when you create local variables also called ROBX and ROBY. As commenters have noted, that will hide both the global variables and the parameters, so you end up only modifying those locally-defined variables.
There are two ways you can fix this:
Don't create local variables and don't pass parameters. Just modify the global variables directly.
Still don't create local variables, and make your function accept two int * parameters. This will allow you to pass in the global variables when you call robot, so you can modify those parameters in a persistent way. See this question for more details.
In either case, you will need to actually call your robot function.
Related
I had this assignment at school, wherein I had to find the output of the following C code, and also, to explain the output.
#include<stdio.h>
int i;
void fun1(void);
void fun2(void);
int main()
{
fun1();
fun2();
return 0;
}
void fun1(){
i=20;
printf("%d\t",i);
}
void fun2(){
int i=50;
printf("%d",i);
}
The output is 20 50
Because in fun1() the Global Variable 'i' is assigned to 20 and printed. And in fun2() the variable 'i' is a Local Variable, which is declared and initialized to 50, which is then printed.
I have this following question out of curiosity, how do I use the global variable 'i', in fun2()?
A simple solution would be to simply change the name and avoid the whole thing. But my curiosity is due to Java, where there is a keyword "this" to access class variable instead of a local variable.
so is there any way to do that in C?
The only way is to hide the declaration of the local variable in a code block.
For example
#include <stdio.h>
int i = 10;
void fun2( void )
{
int i = 20;
printf("local i = %d\n",i);
{
extern int i;
printf( "global i = %d\n",i);
}
}
int main(void)
{
fun2();
}
The program output is
local i = 20
global i = 10
There is no way to access a global parameter inside a function that has a local variable with the same name. It is usually bad practice to create such local variables in C though, as you saw, it is not prohibited.
In C++ you can solve it using namespaces but there is no equivalent in C.
The best way is to pass parameters to the function
void fun2(int fromExternalWorld){
int i=50;
printf("%d ",fromExternalWorld);
printf("%d\n",i);
}
int main(void)
{
fun2(i);
}
Otherwise is not possible to have two symbols with same name visible in the same scope.
You could cheat and create a pointer to the global i before declaring the local i:
void fun2( void )
{
int *ip = &i; // get address of global i
int i = 50; // local i ”shadows" global i
printf( "local i = %d, global i = %d\n", i, *ip );
}
EDIT
Seeing as this answer got accepted, I must emphasize that you should never write code like this. This is a band-aid around poor programming practice.
Avoid globals where possible, and where not possible use a naming convention that clearly marks them as global and is unlikely to be shadowed (such as prefixing with a g_ or something similar).
I can't tell you how many hours I've wasted chasing down issues that were due to a naming collision like this.
I dont have time to explain it deeply, its very simple code but the function always return 'y'(=true)
It is expected to write each number from 1 to squareroot of the generated random number and decide whether it is dividable or not but when i run it, somehow the if statement in the function always return true
#include <stdio.h>
#include <stdlib.h>
int a,b,i;
char c;
char abcd(char c);
int main()
{
srand(time(NULL));
int a=rand()%512;
b=sqrt(a);
i=1;
do{
if(abcd(c)=='y')printf("number %d is dividable by %d\n",a,i);
else printf("number %d is not dividable by %d\n",a,i);
i++;
}while(i<=b);
return 0;
}
char abcd(char c)
{
if(a%i==0)return'y';
else return 'n';
}
When you declare int a inside main as
int a=rand()%512;
you are shadowing your global variable a. The a in main is a different variable that has scope only local to the function main. Therefore, when you are using the value a inside char abcd(char c), this value is the global variable a which is default initialized to 0.
Also, why are you passing a char c variable to function abcd. You aren't using it. Please consider renaming your functions to something that more clearly describes their intent.
You have two different variables a:
one declared at file scope
int a,b,i;
and one declared in main():
int a=rand()%512;
Within its scope (almost all of main()), the latter shadows the former. Elsewhere, such as in function abcd(), only the former is visible. The former is default initialized to 0 and no other value is ever assigned to it, so no matter what value i takes, inside abcd(), the expression a%i evaluates to 0.
This is a good lesson in avoiding file-scope variables. Functions should operate on data accessed directly or indirectly through their parameters, or obtained from an external source. It is poor form for functions to exchange data through file-scope variables. Moreover, it was a red flag to me that your function abcd() declares a parameter that it never uses. Suggested variation:
char abcd(int dividend, int divisor) {
return (dividend % divisor) ? 'n' : 'y';
}
Or even better (because better name and more appropriate return type):
_Bool is_divisible(int dividend, int divisor) {
return !(dividend % divisor);
}
The reason yours doesn't work is because the variable a was declared in a separate scope from the abcd function. The a variable you use inside the abcd function is automatically set to 0, which is why it returns true every time (0 % anything is 0).
When you call abcd, you would need to pass a inside the parameters for it to use the correct value.
But really you don't need the abcd function, you can save a lot of code and directly check if it's divisible. This code should work:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
int a, b, i;
char c;
int main()
{
srand(time(NULL));
int a = rand() % 512;
b = sqrt(a);
i = 1;
do {
if (a%i == 0)printf("number %d is dividable by %d\n", a, i);
else printf("number %d is not dividable by %d\n", a, i);
i++;
} while (i <= b);
return 0;
}
I have a program distributed across a number of files. There are a number of functions which need access to a global array. The issue I'm having is that I don't know the size of the array before the program starts. It opens up a file and then downloads a number of points, and then the array is created with a corresponding size. But for the array to be global, it needs to be declared outside of the main function i.e. before I know the number of points.
What I've tried to do right now is:
file1.c:
#include <stdio.h>
#include "file3.h"
int useful[];
int main()
{
int useful[10];
int i;
for (i = 0; i < 10; i++) {
useful[i] = i+1;
}
SPN();
return 0;
}
file2.c:
#include <stdio.h>
#include "file3.h"
void SPN() {
int i;
for (i = 0; i < 10; i++) {
printf("%i\n", useful[i]);
}
}
file3.h:
extern int useful[];
extern void SPN();
What I'm getting in output is just a bunch of 0s. At first I was thinking that the second int useful[... in file1.c creates a new array with a different internal name, but that doesn't seem to make any sense considering that no segmentation fault is triggered by SPN() when it tries to access memory outside the arrays bounds (if useful[] creates an array and isn't changed, it has default size 1 i.e. < 10). Help?
The int useful[10]; isn't initializing the global int useful[]; or anything like that. It's a new variable, and with the loop here
for (i = 0; i < 10; i++) {
useful[i] = i+1;
}
You're modifying the second useful without touching the global one. This is then discarded at the end of the function.
Instead have a global variable like this:
int *useful;
And initialize it this way:
useful = malloc(sizeof(int)*10);
The declaration of useful inside the main is shadowing the external one.
This means that the values that you think are inserting (in the main) in the global variable are actually going into the local variable.
Take a look at the following article about shadowing for more info.
It might also be interesting to look at scope rules in C.
I'm using C to get a terminal size. That function will be call in the main function. Then I'm hoping to run it again to check if either the terminal size has changed or remain the same. This time the function are called in other function which is run_menu. For additional info, the run menu are also called in the main function. I will explain more in the code. The errors are "too few arguments to function 'get_terminal_size'.
//this function is to get the terminal size
//my idea is to use pointer as it will be use again in other function
void get_terminal_size(int *x, int* y)
{
int cols,lines;
assert(x);
assert(y);
#ifdef TIOCGSIZE
ioctl(0,TIOCGSIZE, &ts);
lines = ts.ts_lines;
cols = ts.ts_cols;
#elif defined(TIOCGWINSZ)
struct winsize ts;
ioctl(0,TIOCGWINSZ, &ts);
lines = ts.ws_row;
cols = ts.ws_cols;
#endif
*x = cols;
*y = lines;
}
//this function is to see either the size has changed or not
int change_terminal_size()
{
int new_cols, new_lines;
int x, y;
get_terminal_size(&x, &y);
#ifdef TIOCGSIZE
ioctl(0,TIOCGSIZE, &ts);
new_lines = ts.ts_lines;
new_cols = ts.ts_cols;
#elif defined(TIOCGWINSZ)
struct winsize ts;
ioctl(0,TIOCGWINSZ, &ts);
new_lines = ts.ws_row;
new_cols = ts.ws_cols;
#endif
log_debug("new lines=%d,new cols =%d",new_lines,new_cols);
if((new_cols !=x)||(new_lines != y)){
return 1;
}
return 0;
}
//this function is to run the menu.
static void run_menu()
{
//bla bla bla with other declaration and function
//i will not write it because its not related
while(1){
if (change_terminal_size()){
log_debug("the terminal has change size");
}
//and it will continue with other things
//this is the main function
int main()
{
//again with other declaration and function not related
get_terminal_size();
run_menu();
//continue on with other thing, then return 0
}
As you can see. I call the "get_terminal_size" function 2 times. Is it related to the problem that im having? As far as I know, if I'm using a pointer, then it shouldn't be any problem.
In here:
//this is the main function
int main()
{
get_terminal_size(); //<---Right here!
run_menu();
}
You don't pass any arguments to get_terminal_size.
get_terminal_size expects to be called with two arguments, thus the error "Too few arguments to function".
"Using a pointer" doesn't really have anything to do with it, nor does "Using a pointer" allow you to use the function from multiple places. All the pointers (x and y) do is allow the function to change values outside of its scope.
Sidebar: you probably ought to have get_terminal_size return a value - in this case probably a struct with an X field and a Y field. Functions that return values via side-effect are more difficult to reason about and more likely to contain bugs, although this particular example is probably fine since you're not mixing input arguments with output arguments.
Also your change_terminal_size() function looks pretty gnarly. Where are you keeping track of the old terminal size so you can compare it to the new terminal size?
get_terminal_size(int*, int*) is a function with two parameters of type int*. In order to call this function, you must pass it the appropriate number of arguments each with the correct type. In main, you call it with no arguments and your compiler complains, as it should.
The main function will need to pass some appropriate arguments - something like below:
int main()
{
//again with other declaration and function not related
int x = 0, y = 0;
get_terminal_size(&x, &y); // &x and &y both have type int*
run_menu();
//continue on with other thing, then return 0
}
You are calling a function which takes two parameters, but you are not using any parameters when you do it. You do use the correct number of parameters in change_terminal_size, which is why that function succeeds.
The good news, though, is that since get_terminal_size does not affect the outside world, you can replace main with:
int main()
{
run_menu();
return 0;
}
# include <stdio.h>
int x = 5;
int main(void)
{
int x = 7;
printf("output = %d\n", x);
}
The above program shows output as 7.
How to print 5 in c?
thanx...
So you're asking how to access a global that's shadowed by a local? You can't in that scope, but something like this should work
# include <stdio.h>
int x = 5;
int get_global_x()
{
return x;
}
int main(void)
{
int x = 7;
printf("output = %d\n", get_global_x());
}
Don't redeclare the x variable in the main function...
In fact, i'm sensing (perhaprs wrongly) that there's another question behind your code, but i'll keep my reaction to it short: if you want to mix global variables and local variables, try to have a convention to distinguish them; for example globals in ALL_CAPS to shout out its scope :)
EDIT: By the way, you should be getting at least a warning from your compiler for redefining a different scope/same name variable. it's really not recommended doing that. Try to always aim for minimum warnings...
You need to give your two variables meaningful names. I'm sure you aren't using x in your real code so do the two vars actually have the same meaning and therefore the same name? If so you could at least do (assuming your ints are counts, but works for all other purposes):
int global_countOfThings = 5;
int main(void)
{
int countOfThings = 7;
printf("output = %d\n", global_countOfThings );
}
But hopefully you'll be able to do something like:
int countOfDucks = 5;
int main(void)
{
int countOfGeese = 7;
printf("output = %d\n", countOfDucks );
}
And of course if you can some how change your code to not use globals you'll be better off in the long run.
You are declaring the same variable in global and local scope. If the same variable is declared in global and local scope, the variable will be treated as local variable. That's the reason you are getting the answer as 7.
Delete the x = 7 line, move the print statement before you print the value or set a different variable to 7 (i.e. write y = 7 instead of x = 7).
u have already declared x to behave as if it is a global variable.to print 5 u can write the pritf statement as:
printf("%d\n",x-2);
The above would print 5.
If you want it 5, why you assign 7? :-) Or you want to access global variable with the same name as local one? Then you might use namespaces... Not sure about C :-)