Declaring a variable in C - c

I’m having a hard time with declaring my variables within C. The compiler display a message “expected constructor destructor or type conversion before token.” What am I doing wrong?
#include <stdio.h>
int count =0;
int abc;
ABC;
a = 19, b = 27, c = 3;
a = 4 + 5 * 3;
b = (4 +5) * 3;
c = 25 -(2 * (10 + (8 / 2)));
main {
printf("Enter a value please\n");
scanf("%d, , \n");
return 0;
}

Here's a rewrite, showing how to fix the various issues:
#include <stdio.h>
int count = 0; // declarations and intitializations are allowed at file
// scope (that is, outside of any function body). The
// storage for count will be set aside at program start
// and held until the program terminates.
//
// count is visible to all functions defined within this
// file, and will be visible to other files compiled and
// linked into the same program.
int main( void ) { // Implicit typing of functions is no longer allowed as of C99,
// and it was never good practice to begin with.
// IOW, the compiler will not assume a return type of
// int if a type specifier is missing. main always
// returns int, and either takes 0 or 2 arguments.
int a, b, c; // int abc; declares a *single* variable named "abc",
// not three variables named "a", "b", and "c".
// Storage for these variables will be set aside at
// function entry and held until the function exits.
//
// None of a, b, or c are visible outside of the
// function body.
// ABC has not been defined anywhere; it's not clear
// what the intent was behind ABC;
a = 19; // While not illegal, a = 19, b = 27, c = 3; is not the best style
b = 27; // in the world; it's better to make these three separate statements
c = 3; // Note that assignment statements (like any other executable
// statement) are not allowed outside of a function body.
a = 4 + 5 * 3; // fine
b = (4 +5) * 3; // fine
c = 25 -(2 * (10 + (8 / 2))); // fine
printf("Enter a value please\n"); // fine
scanf("%d", &a); // Each conversion specifier in a scanf call needs a corresponding
// argument to write the input value to, and the argument needs
// to be of the correct type. %d expects the corresponding
// argument to have type "int *" (pointer to int). The expression
// "&a" gives the address of the variable "a", and the type
// of the expression is "int *". So, this statement will read an
// integer value from standard input and store it to a.
return 0;
}

You cannot write assignments like a = 19, b = 27, c = 3; outside functions.
int count = 0; is the initialisation of a global variable, so that is allowed.
ABC; is also meaningless unless ABC has been #defined to something numerical, and even then it would be a no-op.
main is also malformed. You need to write it as int main() and make sure you return a value.
Lastly, your scanf argument list is not correct. Do consult the documentation.
It would be a good idea to study an introduction to C. Kernighan & Ritchie is an excellent book.

Related

First Element of array not empty, pointer dereference

i am writing code for a microcontroller.
I have the following example so far:
// weekly table[timeslot][day]
const int _rows = 7;
const int _cols = 12;
const int _num_weekly_table = _rows * _cols;
uint32_t weekly_table[_rows][_cols];
// pointer pointing start of array weekly array
uint32_t *ptr_weekly_table = &weekly_table[0][0];
int progress_weekly_table = 0;
bool weekly_table_full = false;
/*
* according to progress_weekly_table save a value in the weekly_table
*/
void append_weekly_table( uint32_t value)
{
//insert element
printf(*ptr_weekly_table);
*(ptr_weekly_table + progress_weekly_table) = value;
//increase progress
progress_weekly_table++;
//if the table is full set flag
if (progress_weekly_table > _num_weekly_table) {
weekly_table_full = true;
}
}
During the main loop I run this line:
append_weekly_table(1);
But the resulting array does not have a 1 as the first element, instead a 3200171746 (reproducable).All other elements in the array are 1 if i continue to run append_weekly_array.
What is my error here? Quite new to pointers so I don't know if this is the issue.
For starters these declarations
const int _num_weekly_table = _rows * _cols;
uint32_t weekly_table[_rows][_cols];
are invalid if they are declarations in the global namespace because 1) you may not initialize a variable with the static storage duration with a non-constant expression and 2) you may not declare Variable Length Arrays with the static storage duration.
It seems you are compiling your program as a C++ program instead of as a C program.
In any case the function append_weekly_table is invalid.
For example this statement
printf(*ptr_weekly_table);
does not make sense because the first parameter of the function has type const char *.
int printf(const char * restrict format, ...);
^^^^^^^^^^^^
And initially the object *ptr_weekly_table has inderterminate value (if the program is a C program and the array does not have the static storage duration; otherwise the object is zero initialized).
Also this condition
if (progress_weekly_table > _num_weekly_table) {
weekly_table_full = true;
}
also is wrong. It should be written like
if (progress_weekly_table == _num_weekly_table) {
weekly_table_full = true;
}
If you want to compile your program as a C program then the variables _rows and _cols must be declared at least like
enum { _rows = 7, _cols = 12 };
Also it is a bad idea to use leading underscores in variable names because such names are reserved by the system.
Here is a demonstrative C program that can compile.
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
enum { _rows = 7, _cols = 12 };
const int _num_weekly_table = _rows * _cols;
uint32_t weekly_table[_rows][_cols];
// pointer pointing start of array weekly array
uint32_t *ptr_weekly_table = &weekly_table[0][0];
int progress_weekly_table = 0;
bool weekly_table_full = false;
void append_weekly_table( uint32_t value)
{
*(ptr_weekly_table + progress_weekly_table) = value;
//increase progress
progress_weekly_table++;
//if the table is full set flag
if (progress_weekly_table == _num_weekly_table) {
weekly_table_full = true;
}
}
int main(void)
{
append_weekly_table( 1 );
printf( "ptr_weekly_table[0] = %d\n", *ptr_weekly_table );
return 0;
}
The program output is
ptr_weekly_table[0] = 1
You could substitute these two statements
*(ptr_weekly_table + progress_weekly_table) = value;
//increase progress
progress_weekly_table++;
//if the table is full set
with one statement
ptr_weekly_table[progress_weekly_table++] = value;
The main problem is most likely this this:
printf(*ptr_weekly_table);
The expression *ptr_weekly_table an uint32_t value. Not a string (char *) which printf expects. Because you in effect pass a null pointer (since ptr_weekly_table[0] is supposedly zero) then you will ask printf to print whatever "string" is at location zero, and that will lead to undefined behavior.
To print the correct value use something like
printf("%"PRIu32"\n", ptr_weekly_table[0]);
See e.g. this format specifier macro reference for information about PRIu32.
And as you can see I used ptr_weekly_table[0] to get the first value of the array. The expressions ptr_weekly_table[0] and *ptr_weekly_table are equal.
In fact, for any pointer or array p and index i, the expression p[i] is exactly equal to *(p + i). Which means *(ptr_weekly_table + progress_weekly_table) could be written ptr_weekly_table[progress_weekly_table] (which is a couple of characters less to write, as well as often more readable).

C: why do I get invalid initializer?

I have to do a function which returns the dot product of two vectors.
Here his the code:
float res;
float v1[3];
float v2[3];
v1[0] = 3;
v1[1] = 2;
v1[2] = 0;
v2[0] = 2;
v2[1] = 5;
v2[2] = 0;
float dotProd(float *vec1, float *vec2) {
return vec1[0]*vec2[0] + vec1[1]*vec2[1] + vec1[2]*vec2[2];
}
res = dotProd(v1, v2)
I thik the function is right, the problem is that I get invalid initializer error when I define the values of the vectors.
What am I missing?
What you are attempting to do is not initialization but assignment. The former is done at the time the variable is defined, while the later is done later as an executable statement. You're getting an error because executable statements are not allowed outside of a function.
You need to use an initializer at the time the arrays are defined:
float v1[3] = {3, 2, 0};
float v2[3] = {2, 5, 0};
float v1[3];
// ...
v1[0] = 3;
v1[1] = 2;
v1[2] = 0;
This: float v1[3]; is a declaration (and a definition). It defines an array object named v1. It can legally appear either at file scope (outside any function) or at block scope (inside a function definition).
This: v1[0] = 3; is a statement. Statements are permitted only inside a function definition.
If you want those statements to be executed just once, you can put them inside your main function.
Execution of your program begins with an implicit call to your main function. Very nearly everything that happens as your program runs results from that, as other functions are called from main, directly or indirectly. If you could have statements outside any function, there would be no way for them ever to be executed. File-scope declarations are permitted, but they're restricted to ones that don't execute any code. For example, a declaration like:
int n = 42;
is permitted either at file scope or at block scope; if it's at file scope the value 42 is loaded into n at program startup. But if the initializer isn't a constant expression, such as:
int r = rand();
then it can only appear at block scope; there's no way to call a function before main starts.
As for why you're getting that particular message, the compiler's parser isn't expecting to see a statement in that context, so it tries (and fails) to interpret v1[0] = 3; as a declaration. When a compiler sees something that's syntactically invalid, it tries to interpret it in a way that lets it give a meaningful error message, but it doesn't always succeed.
Your code is fine; you are probably just having a structure problem.
Try something like:
#include<stdio.h>
float dotProd(float * vec1, float * vec2) {
return vec1[0] * vec2[0] + vec1[1] * vec2[1] + vec1[2] * vec2[2];
}
int main() {
float res;
float v1[3];
float v2[3];
v1[0] = 3;
v1[1] = 2;
v1[2] = 0;
v2[0] = 2;
v2[1] = 5;
v2[2] = 0;
res = dotProd(v1, v2);
printf("%lf", res);
return 0;
}

Passing variable through functions

How would I pass a variable from one function to another in C? For example I want to pass the sumOfDice from function roll and use sumOfDice for the passLine function: Here is my code:
int roll()
{
int dieRollOne = (random()%6) + 1;
int dieRollTwo = (random()%6) + 1;
printf("On Dice One, you rolled a: %d\n", dieRollOne);
printf("On Dice Two, you rolled a: %d\n", dieRollTwo);
int sumOfDice = dieRollOne + dieRollTwo;
printf("The sum of you Dice is: %d\n", sumOfDice);
return sumOfDice
}
int passLine(int sumOfDice)
{
// other code
printf("the sum of dice is: %d\n", sumOfDice);
}
I would have used global variable for sumOfDice, but we are not allowed to. Would I have to pass with asterisk, like: int *num;
Nasim, this is one of the most fundamental concepts in C. It should be well-explained in any C book/tutorial you use. That said, everybody needs to learn somewhere. In order to pass values to/from a function, you start with the declaration of a function.
A function in C may receive any number of parameters but may only return a single value (or no value at all). A function requires those parameters specified in its parameter list. A function declaration takes the form of:
type name (parameter list);
The type is the return type for the function (or void). The parameter list contains the type of variables that are passed to the function. While you will normally see a parameter list in a declaration that contains both the type and name, only the type is required in the declaration. A function definition provides the function code and the function return. The parameter list for a function definition will contain both the type and name of the parameters passed.
(note: you may see old K&R function definitions without any type relying on the fact that the default type is int. That type definition/parameter list is obsolete. see Function declaration: K&R vs ANSI)
Now that you have had a Cliff's-notes version of how to declare/define a function, a short example should illustrate passing/returning values to and from a function. This first example shows the function definitions that precede the main function. In this case no separate declaration is required:
#include <stdio.h>
int bar (int x) {
return x + 5;
}
int foo (int a) {
return bar(a);
}
int main (void) {
int n = 5;
printf ("\n n = %d, foo(%d) = %d\n\n", n, n, foo(n));
return 0;
}
(note: function bar is placed before function foo because function foo relies on bar. A function must always have at minimum a declaration before it is called.)
Another example showing the common use of providing function declarations before main with the function definitions below would be:
#include <stdio.h>
int foo (int);
int bar (int);
int main (void) {
int n = 5;
printf ("\n n = %d, foo(%d) = %d\n\n", n, n, foo(n));
return 0;
}
int foo (int a) {
return bar(a);
}
int bar (int x) {
return x + 5;
}
(note: even though the function foo is defined before bar here, there is no problem. Why? Because bar is declared (at the top) before foo is called. also note: the declaration are shown with the type only, just to emphasize a point, you will normally see int foo (int a); and int bar (int x); as the declarations.)
Use/Output
The output of both is:
$ ./bin/func_pass_param
n = 5, foo(5) = 10
I hope this has cleared up some of the basics for you. If not, you can ask further, but you are far better served finding a good C book or tutorial and learning the language (at least the basics) before you attempt to compile and run a program -- it will take you far less time in the long run.

declaration of variables with same name as global,local and static

I have the following code snippet and I have to analyse what the output will be:
#include <stdio.h>
void f(int d);
int a = 1, b = 2, c = 3, d = 4;
int main(){
int a = 5, c = 6;
f(a);
f(b);
f(c);
printf("%d %d %d %d\n",a,b,c,d);
return 0;
}
void f(int d){
static int a = 0;
a = a + 7;
b = a + d;
c++;
d--;
printf("%d %d %d %d\n",a,b,c,d);
}
The output I've got is as follows:
7 12 4 4
15 26 5 11
21 27 6 5
5 27 6 4
This really baffled me. I noticed that in all 3 function calls the globally declared a suffers the assignment and that in the printf() from main() body the a declared in main() is printed. However, I am not sure about the behaviour of the rest of the variables. Is this undefined behaviour or it actually makes sense?
int a = 1, b = 2, c = 3, d = 4; ---> Global variables
int main(){
int a = 5, c = 6; ---> Shadows the global `a` and `c`
....
void f(int d){
static int a = 0; ---> local static variable visible only inside `f`
...
This is related to C's identifier scopes. The scope of a declaration is the region of the C program over which that declaration is visible. There are six scopes:
Top level identifiers: extends from the declaration point to the end of the source program file
Formal parameters in a function definiton: extends to the end of the function body
Formal parameters in function prototypes
Block (local) identifiers: extends up to the end of the block
Statement labels
Preprocessor macros
What happens in your program is known as overloading of names - a situation in which the same identifier may be associated to more than one program entity at a time. There are 5 overloading classes in C (aka namespaces):
Preprocessor macro names
Statement labels
Structure, union and enumeration tags
Component names
Other names
In C, declarations at the beginning of a block can hide declarations outside the block. For one declaration to hide another, the declared identifiers must be the same, must belong to the same overloading class, and must be declared in two distinct scopes, one of which contains the other.
With this in mind, in your code, local a and c hide global a and c in main(), and a in f() hides global a. All other references are manipulating the global variables.
void f(int d){
**static int a = 0;**
a = a + 7;
b = a + d;
c++;
d--;
printf("%d %d %d %d\n",a,b,c,d);
}
That's right you declared global int a and global void function f
but also you have declared static variable a
Whenever function has called, function is refering a variable of function.
if you want to avoid this problem, you should make a pointer of global variable, and refering a pointed address's value global variable.
As you know static variable is keep their last value until end of program.
each function's variable is exactly going to placed in "Stack" unless allocated by malloc.
And global variable is "Heap".
I am not sure but if you disassembly your program, static value a would go to stack
and treated with PUSH and POP instruction.
In C/C++, the identifiers in a given scope shadow the identifiers in the outer scope from the point of declaration onwards.
The following example demonstrates this:
#include <stdio.h>
const char a[] = "a";
static const char b[] = "b";
void test(const char * arg)
{
const char c[] = "c1";
printf("1-. a=%s b=%s c=%s arg=%s\n", a,b,c,arg);
const char a[] = "a1";
static const char b[] = "b1";
// arg is present in this scope, we can't redeclare it
printf("1+. a=%s b=%s c=%s arg=%s\n", a,b,c,arg);
{
const char a[] = "a2";
const char b[] = "b2";
const char arg[] = "arg2";
const char c[] = "c2";
printf("2-. a=%s b=%s c=%s arg=%s\n", a,b,c,arg);
{
static const char a[] = "a3";
const char b[] = "b3";
static char arg[] = "arg3";
static const char c[] = "c3";
printf("3. a=%s b=%s c=%s arg=%s\n", a,b,c,arg);
}
printf("2+. a=%s b=%s c=%s arg=%s\n", a,b,c,arg);
}
printf("1++. a=%s b=%s c=%s arg=%s\n", a,b,c,arg);
}
int main(void)
{
test("arg");
return 0;
}
Output:
1-. a=a b=b c=c1 arg=arg
1+. a=a1 b=b1 c=c1 arg=arg
2-. a=a2 b=b2 c=c2 arg=arg2
3. a=a3 b=b3 c=c3 arg=arg3
2+. a=a2 b=b2 c=c2 arg=arg2
1++. a=a1 b=b1 c=c1 arg=arg
This output actually makes sense.
In C/C++, the identifiers in a given scope are given preference over the identifiers in the outer scope. In this case in the function main, variables a and c will be used as local variables and rest b and d as global variables. Similarly, in the function void f(int d), d is the passed parameter, a will be used as static whenever the function is called, b and c will be used as global variables.
Hence the output will be calculated.
However you have shown the incorrect output. Correct output must be :
7 12 4 4
14 26 5 11
21 27 6 5
5 27 6 4

c: Style: altering variables in place

Suppose we have something along these lines
int f(int n);
....
do{
int a = b;
int b = f(a);
}
Is there any risk to saying
do{
int b = f(b);
}
instead, assuming a is not used elsewhere? Would it be stylistically preferable to do the former?
It is important to understand that you're not "altering" any variables here, just changing the meaning of a name.
The important concept is called the point of declaration.
Let's look at your example:
int b = 42;
{
int a = b;
int b = 23 * a;
printf("%d\n", b);
}
printf("%d\n", b);
or
int b = 42;
{
int b = 23 * b;
printf("%d\n", b);
}
printf("%d\n", b);
The name b references two objects, depending on where you are in the code, let's call them b1 and b2. This is unsurprising in case 1:
int b1 = 42;
{
int a = b1;
int b2 = 23 * a;
printf("%d\n", b2);
}
printf("%d\n", b1);
Since in C the point of declaration is before the initializer, the second example resolves differently:
int b1 = 42;
{
int b2 = 23 * b2;
printf("%d\n", b2);
}
printf("%d\n", b1);
Note that here there's no link between b1 and b2, you're initializing b2 with its own (undefined) value. A diligent compiler will warn you about this, like
x.c:7:13: warning: 'b' is used uninitialized in this function [-Wuninitialized]
As the compiler parses C code it populates a symbol table, this table contains information about all the different symbols and by symbols I mean identifiers, such as the names you give your variables, functions, and so forth ...
Most C programs are constructed out of nested scopes, global -> function -> component_statements and so on, each scope usually has its own symbol table, so the compiler uses a stack of symbol tables to keep track of everything, when a variable is looked up but isn't defined in the current symbol table it starts the search by going upward the stack until it hits global or usually last table ... but as soon one is defined in the current scope an entry is made 'shadowing' the previous.
heres a simple program to illustrate.
#include <stdio.h>
/* global accessable by most things ... */
int a = 5;
int main()
{ /* function scope */
int a = 4; /* shadowing global */
{ /* nested scope within function scope */
int b = a;
int a = b; /* shadowing function */
printf("%i\n", a);
}
return 0;
}
if you run this you would get 4 which is to be expected but anyone following your code would have to keep in the back of their mind that a is different from all the other a from global, function main ... If the programmer maintaining the code isn't aware of this things or you yourself forgot then you can have subtle run-time bugs that can be quite hard to debug ...
also note that if you run this:
#include <stdio.h>
/* global accessable by most things ... */
int a = 5;
int main()
{ /* function scope */
int a = 4; /* shadowing global */
{ /* nested scope within function scope */
int a = a; /* shadowing function, but not actually accessing outer scope */
printf("%i\n", a);
}
return 0;
}
you wouldn't get 4 but some large random int on my machine its 1606422610 since the variable is being assigned to itself that was just shadow, and c doesn't initialize variables.

Resources