Can I reuse same variable names if they're in different functions? - variables

I'm making a program for the game 15 puzzle.
My function headers look like this:
void leftSlide(vector< vector<int> >& puzzle);
void rightSlide(vector< vector<int> >& puzzle);
void upSlide(vector< vector<int> >& puzzle);
void downSlide(vector< vector<int> >& puzzle);
my main function also has a vector< vector<int> > puzzle. Am I allowed to do this, or will this cause problems?

The scope of a variable is within the enclosing curly braces. For example,
void foo()
{
int x; // variable x is not known outside of foo
}
This scoping rule applies even for variables in the argument list. For example,
void boo (int y)
{
// variable y in not known outside of boo
}
Therefore, in your case, the variables will be passed from the main driver to the individual functions by reference. So, yes, you can have variables of the same name in different scopes.

simply yes
The potential scope of a variable introduced by a declaration in a block (compound statement) begins at the point of declaration and ends at the end of the block. Actual scope is the same as potential scope unless there is a nested block with a declaration that introduces identical name (in which case, the entire potential scope of the nested declaration is excluded from the scope of the outer declaration)

Related

Programming Basics: Variable declaration, intitialiation, assignment, and scope

How does scope interact with variable declaration, initialisation, and assignment? The definition of those terms based on what I have learned so far is listed below:
Declaration: States the type of a variable, and it's name/identifier. Variables must have been declared before they can be assigned or read.
Assignment: Throws away the existing value of a variable and replaces it with a new one, the old value is thrown away at the end of the assignment statement, so the value can be incremented or otherwise adjusted, for example: x = x + y;
Initialisation: The name used for the first assignment of a variable, before initialisation, a variable has a default value, in the case of objects, those objects have a null value. Initialisation can be done in conjunction with declaration.
Scope: The "lifespan" of a variable, a variable is in scope until the end of the code block, at which point the memory used to store that variable is freed up. In effect, the variable is deleted or "killed", when the code block ends.
What I don't know is how scope interacts with Declaration and assignment. While the scope of a variable seems to be based solely on the code block in which it is Declared, I don't know how assignment interacts with scope. For example:
public class exampleClass
{
public static void main(String[] args) // using java for example
{
int x = 5; // x is declared here, and initialised with a value of 5
for (int i = 0; i < 10; i++) // i is declared and initialised here
{
x = i; // x is assigned the value of i each iteration
} // i goes out of scope here
System.out.println(x); // the value of x is printed
} // x goes out of scope here
}
In this example, x is declared and initialised (do we just say initialised?) in the main method, and is in scope for that method. However, x is assigned a value in the while loop. What will be printed when this code is executed, but more importantly why? Will it print "5", or "9"?
I have seen code throw up compiler exceptions because of syntax that would imply that x should print 5. However when I run this example code, I get "9".
One final question, why is it that multiple variables can be declared and initialised inline:
int x = 1, y = 4, z = 6;
But variables cannot be assigned inline:
x = 1, y = 4, z = 6;
The distinction between declaration and initialisation can be blurry; some languages make a clear distinction between these actions, in others initialisation is declaration. If a variable is initialised while it's being declared, it doesn't matter which you call it.
However, x is assigned a value in the while loop. What will be printed when this code is executed, but more importantly why? Will it print "5", or "9"?
9, because that's the last value that has been assigned to it before you print it.
Scope: The "lifespan" of a variable, a variable is in scope until the end of the code block, at which point the memory used to store that variable is freed up. In effect, the variable is deleted or "killed", when the code block ends.
Yes and no. Scope defines in what parts of code a particular variable is available. Different languages can have very different definitions of their scoping rules. A variable is typically garbage collected (in languages where that's applicable) when it goes out of scope, when no piece of code has any further access to it. In a simple function block, that happens when the function ends.
However, see this Javascript example:
function foo() {
var bar = 'baz';
return function () {
alert(bar);
};
}
The inner function which is returned from this function still holds a reference to bar. Even if foo ends, bar is being closed over by a closure and is still in scope within the inner function. As long as a reference to that returned function exists, bar still exists.

I am about to use dlopen() to open shared object. Do I need to include corresponding headers if shared object?

I have to use dlopen() and access functions from shared object in my code. Do I need to include headers of corresponding functions of shared object ?
Because of the way dlopen() and dlsym() operate, I don't see how that would accomplish anything. Very roughly speaking, dlopen() copies the library binary into your program space and adds the addresses of its exported symbols (i.e. global functions & variables) to your program's symbol table.
Because the library was not linked to your program at compile-time, there's no way your code could possibly know the instruction addresses of these new functions tacked on at run-time. The only way to access a run-time dynamically linked symbol is via a pointer obtained from dlsym().
You have to create a function pointer for each and every library definition that you want to use. If you want to call them like regular functions, in C-language you can manually typedef type definitions for the function pointers, specifying their parameters and return values, then you can call the pointers just like regular functions. But note that you have to define all of these manually. Including the library header doesn't help.
In C++ I think there are issues with storing dlsym() output in a typedef'd pointer due to stricter standards, but this should work in C:
addlib.c (libaddlib.dylib):
int add(int x, int y) {
return x+y;
}
myprogram.c:
#include <stdio.h>
#include <dlfcn.h>
typedef int (*add_t)(int, int);
int main() {
void *lib_handle;
add_t add; // call this anything you want...it's a pointer, it doesn't care
lib_handle = dlopen("libaddlib.dylib", RTLD_NOW);
if (lib_handle == NULL) {
// error handling
}
add = (add_t)dlsym(lib_handle, "add");
if (add == NULL) {
// error handling
}
printf("Sum is %d\n", add(17, 23));
dlclose(lib_handle); // remove library from address space
return 0;
}
(Update: I compiled the dylib and myprogram...it works as expected.)

Can a C function be defined within an Objective-C method?

I have a method, like so:
- (void) simpleMethod {
var = someValue;
}
I wanted to define a function which exists only within that method (I can do this in python for example). I tried to define it like a normal C function, like this...
- (void) simpleMethod {
var = someValue;
int times1k(int theVar) {
return theVar * 1000;
}
ivar = times1k(var);
}
But Xcode throws various errors. Is it possible to define a function within a method in Objective-C? And if so, how?
No, Objective-C follows the strict C rules on this sort of thing, so nested functions are not normally allowed. GCC allowed them via a language extension but this extension has not been carried over to Clang and the modern toolchain.
What you can do instead is use blocks, which are Objective-C's version of what Python (and most of the rest of the world) calls closures. The syntax is a little funky because of the desire to remain a superset of C, but your example would be:
- (void) simpleMethod {
var = someValue;
// if you have a bunch of these, you might like to typedef
// the block type
int (^times1k)(int) = ^(int theVar){
return theVar * 1000;
};
// blocks can be called just like functions
ivar = times1k(var);
}
Because that's a closure rather than a simple nested function there are some rules you'd need to follow for declaring variables if you wanted them not to be captured at their values when the declaration is passed over, but none that are relevant to your example because your block is purely functional. Also times1k is a variable that you can in theory pass about, subject to following some unusual rules about memory management (or letting the ARC compiler worry about them for you).
For a first introduction to blocks, I like Joachim Bengtsson's article.

Creating a global "null" struct for re-use in C program?

Not sure what I'm doing wrong here. I have a struct that is used heavily through my program.
typedef struct _MyStruct {
// ... handful of non-trivial fields ...
} MyStruct;
I expect (read, intend) for lots of parts of the program to return one of these structs, but many of them should be able to return a "null" struct, which is a singleton/global. The exact use case is for the implementing function to say "I can't find what you asked me to return".
I assumed this would be a simple case of defining a variable in a header file, and initializing it in the .c file.
// MyStruct.h
// ... Snip ...
MyStruct NotFoundStruct;
-
// MyStruct.c
NotFoundStruct.x = 0;
NotFoundStruct.y = 0;
// etc etc
But the compiler complains that the initialization is not constant.
Since I don't care about what this global actually references in memory, I only care that everything uses the same global, I tried just removing the initialization and simply leaving the definition in the header.
But when I do this:
MyStruct thing = give_me_a_struct(some_input);
if (thing == NotFoundStruct) {
// ... do something special
}
Th compiler complains that the operands to the binary operator "==" (or "!=") are invalid.
How does one define such as globally re-usable (always the same memory address) struct?
This doesn't directly answer your question, but it won't fit in a comment...
If you have a function that may need to return something or return nothing, there are several options that are better than returning a "null struct" or "sentinel struct," especially since structs are not equality comparable in C.
One option is to return a pointer, so that you can actually return NULL to indicate that you are really returning nothing; this has the disadvantage of having significant memory management implications, namely who owns the pointer? and do you have to create an object on the heap that doesn't already exist on the heap to do this?
A better option is to take a pointer to a struct as an "out" parameter, use that pointer to store the actual result, then return an int status code indicating success or failure (or a bool if you have a C99 compiler). This would look something like:
int give_me_a_struct(MyStruct*);
MyStruct result;
if (give_me_a_struct(&result)) {
// yay! we got a result!
}
else {
// boo! we didn't get a result!
}
If give_me_a_struct returns zero, it indicates that it did not find the result and the result object was not populated. If it returns nonzero, it indicates that it did find the result and the result object was populated.
C doesn't allow global non-const assignments. So you must do this in a function:
void init() {
NotFoundStruct.x = 0;
NotFoundStruct.y = 0;
}
As for the comparison, C doesn't know how to apply a == operator to a struct. You can overload (redefine) the operator in C++, but not in C.
So to see if a return value is empty, your options are to
Have each function return a boolean value to indicate found or not, and return the struct's values via pointers through the argument list. (eg. bool found = give_me_a_struct(some_input, &thing);)
Return a pointer to a struct, which can be NULL if nothing exists. (eg. MyStruct* thing = give_me_a_struct(some_input);)
Add an additional field to the struct that indicates whether the object is valid.
The third option is the most generic for other cases, but requires more data to be stored. The best bet for your specific question is the first option.
// MyStruct.h
typedef struct _MyStruct {
// fields
} MyStruct;
extern MyStruct NotFoundStruct;
// MyStruct.c
#include "my_struct.h"
MyStruct NotFoundStruct = {0};
But since you can't use the == operator, you will have to find another way to distinguish it. One (not ideal) way is to have a bool flag reserved to indicate validity. That way, only that must be checked to determine if it's a valid instance.
But I think you should consider James's proposed solution instead
In the header:
// Structure definition then
extern MyStruct myStruct;
In the .c that contains global data
struct MyStruct myStruct
{
initialize field 1,
initialize field 2,
// etc...
};

Difference between value parameter and reference parameter?

Difference between value parameter and reference parameter ? This question is asked sometime by interviewers during my interviews. Can someone tell me the exact difference that is easy to explain with example? And is reference parameter and pointer parameter are same thing ?
Thanks
Changes to a value parameter are not visible to the caller (also called "pass by value").
Changes to a reference parameter are visible to the caller ("pass by reference").
C++ example:
void by_value(int n) { n = 42; }
void by_ref(int& n) { n = 42; }
void also_value(int const& n); // Even though a reference is used, this is
// semantically a value parameter---though there are implementation
// artifacts, like not being able to write "n = 42" (it's const) and object
// identity (&n here has different ramifications than for by_value above).
One use of pointers is to implement "reference" parameters without using a special reference concept, which some languages, such as C, don't have. (Of course you can also treat pointers as values themselves.)
The main difference is whether the object passed is copied. If it's a value parameter the compiler must generate such code that altering the function parameter inside the function has no effect on the original object passsed, so it will usually copy the object. In case of reference parameters the compiler must generate such code taht all operations are done on the original object being passed.
A pointer is a low-level way of representing a reference, so passing a pointer (by value) is how languages like C typically achieve pass by reference semantics.
The difference is pretty simple: direct parameters are passed by value, and the receiver receives a copy of what is passed; meaning that if the parameter is modified by the receiver, these changes will not be reflected back to the caller. (This is often called, appropriately enough, pass by value, or by copy.
There are basically three kinds of parameters; pointer, reference and direct.
The difference is pretty simple: direct parameters are passed by value, and the receiver receives a copy of what is passed; meaning that if the parameter is modified by the receiver, these changes will not be reflected back to the caller. (This is often called, appropriately enough, pass by value, or bycopy.
Pointers are also passed by value, but rather than sending the actual value, the caller sends the address of the value. This means that by following this pointer, the receiver can modify the argument. Note that changes made to the actual pointer still aren't reflected back to the caller.
The final form, call-by-reference, is sort of a middle ground between these two approaches. Essentially it can be thought of as a pointer that looks like a value.
It is worth mentioning that at the core of it all, parameters are always passed by value, but different languages have different ways of implementing reference semantics (see Kylotans answer).
// Example using C
// bycopy
int multiply(int x, int y) {
return x * y;
}
void multiply_p(int *x, int y) {
*x *= y;
}
int main () {
int i, j, k;
i = 20;
j = 10;
k = multiply(i,j); // k is now 200
multiply_p(&i, k); // i is now 4000 (200 * 20)
return 0;
}
Pseudocode:
Pass by Value:
void setTo4(value) { // value is passed by value
value = 4;
}
int x = 1;
setTo4(x);
// x is still 1
Pass by Reference:
void setTo4(value) { // value is passed by reference
value = 4;
}
int x = 1;
setTo4(x);
// x is 4