the defined variable is different - c

why is the variable in the average function is different from the same variable in the main function? I do not know how to solve it because I'm just learning.
#include <stdio.h>
#define SIZE (sizeof(number)/sizeof(int))
int number[] = {5,65,84,25,644,2};
int average(int *number)
{
printf("size = %ld\n",SIZE);
int sum=0;
for(int i=0;i<=SIZE ;i++)
{
sum += number[i];
}
return sum/SIZE;
}
int main()
{
printf("average : %d\n",average(number));
printf("number of elements: %ld\n", SIZE);
return 0;
}

You use a macro (i.e. #define ...) to specify SIZE. The macro is expanded "textually" wherever you make use of it, and it is interpreted in the respective context, i.e. it's meaning depends on where you place it.
So in main, number as part of your macro refers to the global variable number, whereas in the context of function average, it refers to the function argument number (which hides the equally named global variable).
Anyway, it's impossible to deduce any array size from a pointer variable. You'll have to pass the number of elements as an extra argument.

Within main, number is a global variable which is an array. So sizeof(number) gives you the size of the whole array in bytes.
In the average function however, number is a parameter to the function and has type int *. So sizeof(number) in that case gives you the size of the pointer, not the size of the array.
Either don't pass a parameter and just use the global, or pass the size of the array as a separate parameter to the function.

You have defined a global variable number which is an array.
In the function average , you defined another variable with the same name/identifier number (although of different type i.e. a pointer).
Now, when you use number inside the main function you are actually using the pointer number and not the global variable number. This is also known as variable hiding.
If you want to use the global variable change the name of the argument of the average function to something else or you can go the hard way and do something like this.
Happy Coding;)

Related

a C Program to create two variables with 10 and 20 and print their sum using pointer

#include<stdio.h>
int sum(int*a,int*b)
{
int s=0;
s=*a=*b;
return s ;
}
int main()
{
int num1=10 , num2=20 ,*ptr1 ,*ptr2 ,sum=0 ;
ptr1=&num1;
ptr2=&num2;
sum = sum(*ptr1,*ptr2);
printf("sum of two variables is %d",sum);
return 0;
}
//it is showing "main.c:18:8: error: called object ‘sum’ is not a function or function pointer"
//how to solve this error
You can't use the same name for a local variable and a function. You called them both sum. The compiler is getting confused about which one you want. Change the name of one of them.
You get The Error because you cant use the name "sum" twice.
Further your code contains a two more problems:
you can't just declare a pointer without a type, since they are of different length depending what they are referencing.
your function expects a pointer not an address, but you are giving it the value of the pointer.
BTW you could solve the problem without declaring so much extra stuff, even if you want to work with an extra function and pass along pointers :)

how to work with parameters in fixes, the fixes are pointers?

I want to generate a 16x16 matrix of characters that contains the letter "o" in upper case, and then save it in a text file
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<conio.h>
char generate_matrix(){
int colum=16,j;
int rows=16,i;
for (i=0;i<rows;i++){
for(j=0;j<colum;j++){
matrix[i][j]='O';
}
}
return matrix;
}
void save(char matrix[16][16]){
FILE*archivo;
int i,j;
char address[]="C:\\Users\\Usuario\\Desktop\\mat.txt";
archivo=fopen(addres,"w");
if(archivo==NULL){
printf("does not exist");
}
else{
printf("exist");
}
for(i=0;i<16;i++){
for(j=0;j<16;j++){
fprintf(archivo,"%c\t",matrix[i][j]);
}
fprintf(archivo,"\n");
}
fclose(archivo);
}
int main(void){
generate_matrix();
save(matrix);
return 0;
}
ERROR
In function 'generate_matrix': error: 'matriz' undeclared (first use in
this function)
matrix[i][j]='O';
^~~~~~
note: each undeclared identifier is reported only once for each function it appears in matrix.c: In function 'main':
error: 'matriz' undeclared (first use in this function)
save(matrix);
^~~~~~
please help me, I'm just starting in c
I do not know if the error is because I have to pass the matrix by pointer?
or how can I pass it as a parameter
First of all, you never declared "matrix" anywhere. So of course the compiler doesn't know what "matrix" is because you never told it what it is.
Just like how you declared "i" and "j" as "int i,j" and address as "char address[][]". Those lines tell the compiler what those variables are supposed to be. You never declared what "matrix" is supposed to be so the compiler throws a "'matrix' undeclared" error.
You also need to understand scope.
When you declare a variable, it is only valid the scope it is declared in. A variable can have a very narrow scope or it can have a very wide, global scope. One way you can think of scope is in terms of curly braces (these things: {}). Variables declared within curly braces are only valid within the curly braces they were declared in. Once you leave those curly braces, the variable is lost.
One solution you could do would be to declare your "matrix" variable with a global scope. That is, put the declaration at the top of your code outside of any curly braces. This will make the matrix capable of being used by anything within the code.
Although, doing this is typically considered bad practice because using a lot of global variables can get really cluttered really fast and possibly lead to conflicts when incorporating this code into a large project.
Instead, you could declare "matrix" within the "generate_matrix()" function as well as the "main()" function. You could also pass in the array representing the matrix defined within the "main()" function into the "generate_matrix()" function. The "generate_matrix()" function could then modify that matrix. This will make it so that the matrix declared within "main()" is the same matrix that "generate_matrix()" is modifying.
I notice you say "I have to pass the matrix by pointer". You are using an array to represent your matrix, and arrays ARE pointers. When you say something like "char matrix[16][16]", the keyword "matrix" is simply a memory address pointing to where the data for this array is stored. Saying something like "matrix[i][j]" is simply deferencing that pointer using "i" and "j" to calculate the offset.
Since arrays are just pointers, so you aren't copying the matrix values when you pass it into a function. You are copying the value of the pointer, which points to where your array is in memory. So if you pass in a matrix to a function and then modify that matrix, you will be modifying the same matrix that was passed into it, not a copy of it.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//Returns nothing because it modifies the matrix passed into it
void generate_matrix(char matrix[16][16]) {
int colum=16,j;
int rows=16,i;
for (i=0;i<rows;i++) {
for(j=0;j<colum;j++) {
matrix[i][j]='O';
}
}
}
void save(char matrix[16][16]) {
FILE*archivo;
int i,j;
char address[]="mat.txt";
archivo=fopen(address,"w");
if(archivo==NULL) {
printf("does not exist");
}
else {
printf("exist");
}
for(i=0;i<16;i++) {
for(j=0;j<16;j++) {
fprintf(archivo,"%c\t",matrix[i][j]);
}
fprintf(archivo,"\n");
}
fclose(archivo);
}
int main(void) {
char matrix[16][16]; //matrix initially declared here
generate_matrix(matrix); //modify that matrix
save(matrix); //save it
return 0;
}
You can see the changes I made. I made it so "generate_matrix()" doesn't return anything anymore. Instead, you pass an array into it and it modifies that array. So that allows us to declare the array underneath "main()", pass it into "generate_matrix()" to get modified, then pass it again into "save()".
I also removed "conio.h". That's not part of C standard and is never used by your program. It's not good practice to include libraries that are platform-specific that are unnecessary, because that makes your code unnecessarily unportable.
Finally, I fixed your typo where you referred to "address" as "addres". I also changed your path to save the file because I am not on Windows so I couldn't test the program with that path.

Implicit declaration of function is invalid in C99

I am new to C language and I am having a problem that I really don't understand. I am trying to get an array from another function but when I try to extract the information, it gives me the following warning:
Implicit declaration of function 'getk_vector_calculation' is invalid in C99
Array initializer must be an initializer list or string literal
Here is the code:
int k_vector_calculation(int krec[3])
{
...
krec [0] = l*u[0]+m*v[0]+o*[0] ;
krec [1] = l*u[1]+m*v[1]+o*[1] ;
krec [2] = l*u[2]+m*v[2]+o*[2] ;
return k_vector_calculation( &krec[3] )
}
int main ()
{
char krec[3] = getk_vector_calculation(&krec[3]);
...
}
in your main() the function you called is getk_vector_calculation() [which is not k_vector_calculation()] and which is not declared or defined before the usage.
To resolve this,
either #include the header file containg the declaration of getk_vector_calculation() in your sorce file. [Considering getk_vector_calculation() is in some other file]
or, add a forward declaration of getk_vector_calculation() before main() and define getk_vector_calculation() somewhere.
To know more about implicit declaration, you can check this question.
EDIT:
As others have pointed out, there are many more problems in your code snippet. But since the question title is limited to implicit declaration error, IMO, this answer should do the needful. The remaining error(s) is(are) altogether a different aspect.
In older versions of C, functions that had not been declared yet were still able to be called, and it was assumed that they returned int and took an unspecified number of arguments. Strictly speaking, in C99, it is not permitted to call a function without declaring it first.
In your case however, you are trying to call a function called getk_vector_calculation but you have defined a function called k_vector_calculation (no get at the beginning).
You are also trying to initialise an array using a function, which is not permitted (in C, functions cannot return arrays). Simply declare the array and call k_vector_calculation as a separate statement, e.g.:
int krec[3] = {0};
k_vector_calculation(krec);
Don't use &krec[3] as this points to an invalid location. Use &krec[0] to provide the address of the first element in the array, or equivalently just krec will do. N.b. also that you declare an array of type char, but your function accepts a pointer to int, and these types are not compatible. Your function also calls itself unconditionally so there is a guaranteed infinite recursion if the snipped out code does not conditionally return. If your function doesn't need to call itself, and it doesn't return a value of any importance, change the return type to void to indicate it has no return value.
Since you are using C99, you can take advantage of using the static keyword in your function's parameter declaration:
void k_vector_calculation(int krec[static 3])
{
// ... other code here ...
krec[0] = l*u[0]+m*v[0]+o*[0];
krec[1] = l*u[1]+m*v[1]+o*[1];
krec[2] = l*u[2]+m*v[2]+o*[2];
}
The above code declares a function that takes as an argument an array of at least 3 int.
Several issues, here:
As Sourav Ghosh pointed out, you define k_vector_calculation(), but then try to call getk_vector_calculation(). You have to use the right names.
You say you want to "get an array from another function" - you just can't do this in C.
You don't show all your code for k_vector_calculation(), but as shown, this function will call itself forever, because the last thing it does is to unconditionally call itself again. If you have a recursive function, you need to give it a way to terminate.
&krec[3] is the address of the fourth element of the array k, which is not want you want to be doing, here, especially since your array only contains 3 elements. To refer to the array itself, just use krec.
char krec[3] = getk_vector_calculation(&krec[3]); is invalid for numerous reasons. One, you can't initialize arrays in this way in C. Two, see point (4) for your argument. Three, even if you could initialize arrays this way in C, you'd be trying to pass an uninitialized array to a function, initialize it in there, and then try to initialize your original array with the result. It just makes no sense.
You also write your functions to work with an array of int, but declare krec in main() as an array of char.
It's not clear what you want k_vector_calculation() to do, but you just can't return arrays in C like that. Probably what you want to do is just pass the array to the function, have the function work on in, and return nothing. For instance:
#include <stdio.h>
void k_vector_calculation(int kvec[])
{
kvec[0] = 1;
kvec[1] = 2;
kvec[2] = 3;
}
int main(void)
{
int kvec[3];
k_vector_calculation(kvec);
for ( int i = 0; i < 3; ++i ) {
printf("kvec[%d] is %d.\n", i, kvec[i]);
}
return 0;
}

Make an array accessible to any subunit included using #include "unit.c"?

How do I make sure a function from unit.c called from my main.c that needs an array declared in main.c functions properly?
Is there any way to declare variables globally across .c files? Is there a smart way to do it without using global variables?
Example:
#include <stdio.h>
#include "sub.c"
int main(void)
{
int matrix[5][5];
matrix[5][1] = 5;
Range();
}
Now for sub.c:
int Range()
{
printf("Your Range is: %i",Matrix[5][1])
}
Now the problem occuring is that now upon compiling there will be errors saying that
"In file included from main.c:
"sub.c:3:15: Error: Matrix not declared"
Or something along those lines.
So, several things:
Don't #include .c files (that is, source code); this is a bad habit to get into. For a small, simple program like this it's not a big deal, but as your programs become bigger and more complex, it will cause build and maintenance headaches. What you want to do instead is define a header file that only includes the declaration of your function, rather than the definition (body) of it, something like the following:/**
* sub.h - declaration for Range function
*/
#ifndef SUB_H // include guards; prevents this file from being processed
#define SUB_H // more than once for the same translation unit
/**
* Changing the type of Range to void since you aren't returning anything, and you
* aren't using the result of the function in your main function
*/
void Range( /* parameter declarations, which we'll get into below */ );
#endif
You'd then #include this file as #include <stdio.h>
#include "sub.h"
int main( void )
{
int Matrix[5][5];
Matrix[5][1] = 5; // this is an error; your array dimensions only go from 0 to 4
Range( /* parameters, including Matrix, which we'll get into below */ );
}
and compile your sub.c separately and link the resulting object files together.
Don't use global variables if you can help it; ideally, functions and their callers should communicate exclusively through parameters, return values, and exceptions (in languages which support exceptions, anyway, which C doesn't). You should pass Matrix as a parameter to your Range function, along with parameters for the array's size, and any additional information required by the function to do its job. Since you want to print the value of a single element, you should pass the row and column number of that element as well.
Now, here's where things get headachy - C's treatment of array expressions is a little non-intuitive. Except when it is the operand of the sizeof or unary & operators, or is a string literal being used to initialize another array in a declaration, an expression of type "N-element array of T" will be converted ("decay") to an expression of type "pointer to T", and the value of the expression will be the address of the first element of the array.
If you pass the array as a parameter like so:Range(Matrix);
then type of the expression Matrix is "5-element array of 5-element array of int". Since this expression is not the operand of the sizeof or unary & operators, it is converted to an expression of type "pointer to 5-element array of int", and the value is the address of the first row of the array (which is the same as the address of the array itself). That means your Range function would be declared as something likevoid Range( int m[][5] )
orvoid Range( int (*m)[5] ) (the parentheses in the second declaration matter; without them, m would be declared as an array of pointers to int, which is not what we want).
In the context of a function parameter declaration, T a[] and T a[N] are both interpreted as T *a; that is, a is declared as a pointer to T, not an array of T.
Note that, since you passed the address of the array to the function, any changes the function makes to the array will be reflected in the caller; that is, if Range changes the value of m[4][0], you'll see that changed value in Matrix[4][0].
Since we only specify the number of columns in the declaration for m, we want to pass an additional parameter specifying the number of rows. C doesn't do any bounds checking on array accesses, meaning you can write something likex = m[20][1]; without getting a warning at compile time or guaranteeing a crash at runtime. So you need to do that bounds checking yourself, meaning you need to know how many rows the array has, in addition to the number of columns. You would pass a separate parameter for the number of rows:code>Range(Matrix, 5);
meaning your function declaration would look something likevoid Range(int m[][5], size_t rows);
One flaw with the above approach is that the number of columns in m is fixed at 5; this function won't be able to work on matrices of other sizes. If you're
working with a compiler that supports variable-length arrays1, you can use a variable to specify the array dimensions, rather than a compile-time constant. Since the variable needs to be declared before it can be used in an array declaration, you'd have to write the prototype asvoid Range( size_t rows, size_t cols, int m[][cols] );
and call the function asRange(5, 5, Matrix);
This will allow you to use the Range function on matrices of different sizes, such as:int M1[5][5];
int M2[9][9];
int M3[20][20];
...
Range(5, 5, M1);
Range(9, 9, M2);
Range(20, 20, M3);
Now, if you only intend for this function to work with 5x5 matrices, then hardcoding the dimension isn't a problem; it's only an issue if you intend to use this function for any sized matrix.
If you are using a compiler that doesn't support VLAs, you'll need a different approach. Instead of passing the array expression as a parameter, we pass a pointer to the first element of the array. We'll treat this pointer as though it were a 1-d array instead of a 2-d array, like so:void Range( int *m, size_t rows, size_t cols )
{
printf("Your range is: %d\n", m[4 * cols + 1]);
}
and you would call it asRange(&Matrix[0][0], 5, 5);
You're assuming the presence of an element at Matrix[5][1]; however, arrays in C are 0-origin, meaning that both dimensions are indexed from 0 to 4. So to access the 1st element of the 5th row, you'd refer to Matrix[4][0]. Matrix[5][1] is outside the bounds of your array.
This also brings up the question of whether you're ever going to want to check an element other than m[4][0]. If you want the function to access any arbitrary element of the array, you will want to pass the row and column number as separate parameters; this, combined with passing the array's dimensions as parameters, gives you a way to make sure you aren't trying to access an element outside of the array's bounds. So, your Range function would look something likevoid Range(int m[][5] size_t rows, size_t i, size_t j)
{
if ( i < rows && j < 5 )
printf("Your range is: %d\n", m[i][j];
}
and you would call it asRange(Matrix, 5, 4, 0);
Which brings us to our last item (finally); don't use "magic numbers" in your code. Instead of splashing the literal 5 all over the place, define symbolic constants (preprocessor macros) to represent the number of rows and columns in your matrix. For one thing, if you decide to change the array dimensions, you only need to update the constant definitions, rather than chase down every occurrence of the literal 5 and determining whether it's being used to check your array access. Putting all of the above together (and assuming you're okay with Range only working with arrays of a specific size), we get:/**
* sub.h - declaration for Range function
*/
#ifndef SUB_H // include guards; prevents this file from being processed
#define SUB_H // more than once for the same translation unit
/**
* Since these macros are going to be used by both the main function
* and the Range function, it makes sense to define them in the
* sub.h file, as it will be included in both main.c and sub.c
*/
#define ROWS 5
#define COLS 5
/**
* Prints the value at index i,j of m; if i or j are out of
* range, prints nothing.
*/
void Range( int m[][COLS], size_t rows, size_t i, size_t j );
#endif
/**
* sub.c - implementation of Range function
*/
#include <stdio.h>
#include "sub.h"
void Range( int m[][COLS], size_t rows, size_t i, size_t j )
{
if ( i < rows && j < COLS )
printf("Your range is: %d\n", m[i][j]);
}
/**
* main.c
*/
#include <stdio.h>
#include "sub.h"
int main( void )
{
int Matrix[ROWS][COLS];
Matrix[4][0] = 5; // assumes we know 4 and 0 are within
Range( Matrix, ROWS, 4, 0 ); // the array bounds.
}
So, are you thoroughly confused yet?
1. A C99 compiler, or a C2011 compiler where the macro __STDC_NO_VLA__ is either undefined or 0. Some C89 compilers may support VLAs as an extension.
You should have a header file which have the prototype of the function you need to call and include it. I don't think you include the .c file
You also need to pass parameter to the function.
If you need to access variables across files, you need to use extern variable.
Good programming practices dictate to use them as parameters, so the option'd be:
#include <stdio.h>
#include "sub.h"
int main(void)
{
int matrix[5][5];
matrix[5][1] = 5;
Range(matrix);
}
Where sub.h includes only the prototype of the funcion.
Now for sub.c:
int Range(int matrix[][5])
{
printf("Your Range is: %i",matrix[5][1]);
return 0;
}

"Compound Literals" as an Argument

Calling the function sum(int [], arr_size) in the statement
total = sum((int []){1,2,3,4,5}, 5);
a Compound Literal (int []){1,2,3,4,5} is passed as argument. It is clear that the length of array is determined by numbers of elements in literal(which is of-course 5 here). Then what is the need of passing 5 as another argument?
can't we define above function as
sum(int []) {....}
and then calling it as
total = sum((int []){1,2,3,4,5})
?
Your function sum is identical to sum(int *, size_t); the square brackets are just syntactic sugar. No arrays are passed at any point, and indeed you cannot pass arrays as function arguments in C. Thus there is no size information left in the "array" part of the function parameters, and the size must be passed separately.
You can define sum that way and call it as shown in your example, but in that case you will not be able to determine the size of the array inside the function.
What you could do is declare sum as
int sum(int (*a)[5])
{
...
}
and then call it as
total = sum(&(int []){1,2,3,4,5});
But in this case you will be restricted to arrays of size 5 only. If you want to have a function that works with arrays of any size, you have to either pass the size from outside or reserve some sort of "terminator" element in your array

Resources