Variable character inside a constant - c

Having defined this:
int var1 = 1;
int var2 = 2;
int var3 = 3;
I want to make this:
int result = varc * 70; // Where c is a previously defined int that can take 1,2 or 3 value.
Solutions? Thank you.

In C you're out of luck on this since it's not a reflective language. That is you can't get the value of a variable by somehow "stringifying" the name you gave it in the source code.
But what you could do is use an array:
int vars[] = {1, 2, 3};
int result = vars[i] * 70;
where i is 0, 1, or 2.

you write:
int result = varc * 70;
This is what you want to make is not possible in language c.
Note: varc is an identifier
Remember IDENTIFIER in C :
Identifiers are names for entities in a C program, such as variables, arrays, functions, structures, unions.
It must be unique for all entities and also an identifier is a string of alphanumeric characters
Ok, you remembered. :)
So, you never used "c" present in "varc" to treat(refer) to other variables/identifies/entities.
I hope I might be solve your doubt in easiest way .Thank you! :)

Related

Why to assign values to variables only after declaration

I know there must be a duplicate, but I didn't find anything. In C, I see a lot of code examples where the authors only assign values after the declaration of the variable, is there a good reason for doing that?
int main(void)
{
int x; // declare "x"
x = 5; // assign 5 to "x"
return 66;
}
And what's the different between that and just declaring and assigning a value in one line?
int main(void)
{
int x = 5; // declare "x" and assign in the same line
return 66;
}
It's mostly a matter of style these days. In many cases it's less error prone to assign a value to a variable at the point where it's first used, and perhaps as close to its point of first use as possible.
On the other hand, I've certainly seen cases where an algorithm is easier to follow when it isn't dotted with statements that introduce new variables. Collecting up all these statements before the main body of the algorithm may allow the algorithm itself to fit on a single page/screen.
And it seems pointless to assign an initial value to a variable in a construction like this:
int foo;
if (bar == 42)
foo = 1;
else
foo = -1;

Is it a good practice to group related constants using structs in C?

I was wondering if it would be a good idea to use structs as pseudo namespaces (à la C++) to group constants which are functionally or conceptually related to each other.
static const struct {
const unsigned int START;
const unsigned int END;
} COUNTER = {.START = 1, .END = 100};
Is there any downside to this? If not, is it redundant (or maybe even unconvenient) to have both the struct instance and its members declared as const? Where should the constantness of these values be stated?
I was wondering if it would be a good idea to use structs as pseudo namespaces
Well, it CAN be a good idea. It's not intrinsically bad. An argument against is that if you feel that you need namespaces, then it's likely that C is the wrong language in the first place. But it can be used this way, and it is sometimes used this way.
Where should the constantness of these values be stated?
It's in general enough to declare the whole struct as const. But beware with pointers. This code is valid and will print "42":
int x = 5;
const struct {
int *p;
} S = {.p = &x };
int main()
{
*(S.p) = 42;
printf("%d\n", x);
}
In the above code, you are not allowed to change S.p so that it points to something else, but there is a difference between a const pointer and a pointer to const. So for pointer, it could be a good idea to add an extra const.
To clarify, the pointer p will be declared like it was a int * const p which means you cannot change the pointer itself, but in order to protect the data it's pointing to, you need const int *p. To get both, use const int * const p, but if the struct is declared as const, you'll get one of them "for free" so const int *p is enough to get both.
And if you consider pointers to pointers, well, think it through for a long time and test it to make sure it works the way you want.
From comments:
Why not enums?
Because this is not valid:
enum S {a = 5};
enum Y {a = 6};
The compiler will tell you that a is already defined. So enums is not good for emulating namespaces. Also, you cannot use enums for non-integers.
Is it a good practice to group related constants using structs in C?
It's opinion based. If it works for you, do it.
I wouldn't do like that i C. Instead I use #define
Like:
#define GROUPNAME_NAME
so in your case I would do
#define COUNTER_START 1
#define COUNTER_END 100
In C++ I would do:
const unsigned int COUNTER_START = 1;
const unsigned int COUNTER_END = 100;
The difference between C and C++ is due to differences in language specification.

"Variable may not be initialized" when specifying the array size with another variable

I am trying to compile the following code:
int rows = 4;
int columns = 4;
int numblock[columns][rows] = {
{0,0,0,0},
{0,0,0,0},
{0,0,0,0},
{0,0,0,0}
};
And it tells me that the variable may not be initialized. When I write int numblock[4][4] instead, the compiler doesn't complain.
I guess it is related to this: C compile error: "Variable-sized object may not be initialized"
Can someone please explain this to me?
Edit - from a comment by op:
.. I set columns and rows = 4. It should know the size, shouldn't it?
The answer is already in the link you provide but I'll try to clarify as the linked answer wasn't clear to you.
First - what you have is called VLA, i.e. a Variable Length Array. The idea is simply that you can use another variable to set the size of the array. So this allows the size to be set at run time.
The problem you have is because: It is not allowed to initialize a VLA
It is as simple as that - it is just not supported in C.
It works fine with the initializer when the array is defined with numbers (e.g. [4][4]). That is because the size of the array is known at compile time
The fact you you initialize rows and columns to 4 makes no difference. The compiler do not track whether these variables are changed before the array is created. For instance like this:
void foo()
{
int rows = 4;
int columns = 4;
rows = rows + 42; // or scanf("%d", &rows) to get the number of rows from a user
int numblock[columns][rows]; // no - initializer here - not allowed
}
Even if you make rows and columns constants - like const int rows = 4; - it still won't work in C (but in C++ it will).
One way to "initialize" a VLA is to use memset - like:
void foo()
{
int rows = 4;
int columns = 4;
int numblock[columns][rows]; // no - initializer here - not allowed
memset(numblock, 0, sizeof numblock); // but using memset is easy
}
If you want a fixed number of rows/columns the C way is to use defines. Like:
#define ROWS 4
#define COLUMNS 4
void foo()
{
int numblock[ROWS][COLUMNS] = {
{0,0,0,0},
{0,0,0,0},
{0,0,0,0},
{0,0,0,0}
};
}
This will work because defines are resolved at compile time
I found that if I initialize n at 0 in the variable declarations, but do not initialize the array until inside of the body of the program (int main ()), that the compiler does not complain and the program functions as expected. This may not be the preferred way, and I think perhaps the use of #define may be a more elegant way.

how do i print output as 5 of the following program?

# 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 :-)

C: Behaviour of the `const` keyword

I've been told that if I'm coding in ANSI C to declare in the order that the variables will be used, assert that pointers are not null and that indices are within bounds, and to initialize just before usage of the variable.
If I declare a const can I initialize it after a block of assertions and code?
In Java final initializations must occur at declaration, yet is it consistent through ANSI C implementations that I can initialize a const once, but not necessarily at the time of declaration?
The Java compiler has a small amount of flow logic to allow you to initalise final variables after their declaration. This is legal Java:
final int something;
if ( today == Friday )
something = 7;
else
something = 42;
Java will detect if any branches leave the final value undefined. It won't analyse the conditions, so this is not legal Java, even though it's logically similar:
final int something;
if ( today == Friday )
something = 7;
if ( today != Friday )
something = 42;
In ANSI C89, const variables ( other than extern ) must be initialised in the statement they are declared in.
const int something = ( today == Friday ) ? 7 : 42;
The extern modifier on a declaration tells the compiler that the variable is initialised in a different complation unit ( or elsewhere in this compilation unit ).
In ANSI C99, you can mix declarations and code, so you can declare and initialise a const variable after a block of assertions and code. Portability of 1999 ANSI C remains an issue.
A work around for C89 is to note that the rules for declarations preceding code work at block scope rather than function scope, so you can do this:
#include<stdio.h>
int main ( void )
{
printf ( "wibble\n" );
{
const int x = 10;
printf ( "x = %d\n", x );
}
return 0;
}
Be aware that even in C89, you can often move the definition closer to the point of first use by introducing a bare block just for the extra scope. Before:
int a, b, c;
a = 12;
// Do some stuff with a
b = 17;
// Do some stuff with a and b
c = 23;
// Do some stuff with a, b, and c
After:
int a = 12;
// Do some stuff with a
{
int b = 17
// Do some stuff with a and b
{
int c = 23;
// Do some stuff with a, b and c
}
}
With C99 of course, you can define variables other than at the beginning of a block:
int a = 12;
// Do some stuff with a
int b = 17
// Do some stuff with a and b
int c = 23;
// Do some stuff with a, b and c
const variables are read-only and must be initialised where they're defined.
This code produces error: assignment of read-only variable 'foo' (GCC 4):
const int foo;
foo = 4;
The same goes for const pointers (note here: const int * is not a const pointer, but a pointer to const):
int * const foo;
foo = 4;
Short of the block scope and C99 declaration methods other have shown, the answer is no; you cannot defer initialization of a const variable. Anyway, const is not very useful for local variables. The main times I use the const keyword in C are:
Pointers in function arguments (or local variable pointers based on arguments) where the function is honoring a contract not to modify the pointed-to data. The const keyword helps ensure that the function implementation respects the requirement not to modify (it requires special effort casting to get rid of const) and allows this requirement to propagate through multiple function calls.
For declaring compile-time constant tables (lookup tables, predefined permanent objects, etc.) which I want stored in a read-only section of the binary so they don't use extra physical resources at runtime.
I sometimes declare local variables const if I think it will assist the reader in understanding a function, but that's pretty rare.
You can't initialize the const after declaration within the function body, but you can just open one block after your assertions:
void func()
{
int y;
// Do assertions
assert(something);
{
int const x = 5;
// Function body
}
}
If you are talking of splitting a definition
const int x = 2;
into two parts:
const int x;
x = 2;
I'm afraid that's not possible in C.
If I were you, I would try to make sure I understand the intent of the coding rules that you describe. I doubt sane coding rules would prevent initializing variables (even non-const variables).
In response to various comments:
const int * p;
is not a declaration of a const variable. It is a declaration of a non-const pointer variable to a const int.
You can declare
extern const int x;
but you can still not initialize x after having executed code, assertion checks, etc.
If you'd like to cast away const on the LHS, use this:
const int n = 0;
*((int*)&n) = 23;

Resources