Making a variable accessible by other functions in C - c

I'm new to programming and we just learned arrays in class.
We are tasked to create a C program without using global variables.
I created two functions, one for inputting the data and one for the operations (containing a menu). After making the user choose which operation he would like to do in the operations menu, it will display the result and return back to the menu.
I couldn't figure out how to make some of the variables readable by the operations function since we are not allowed to use global variables.
void matrix(){
int a, b, c, d, k, m, n, p, q, s=0, first[MAX][MAX], second[MAX][MAX], msum[MAX][MAX], firstt[MAX][MAX], secondt[MAX][MAX], prod[MAX][MAX];
system("CLS");
printf("/-----------------------------------------------------------------------------/\n"
"\t\t\t\tMatrix\n"
"/-----------------------------------------------------------------------------/\n");
printf("This program will multiply matrices (up to 3x3 matrix only).\n"
"Please enter the number of rows of the first matrix: ");
scanf("%d", &m);
if(m>3){
matrixerror();
}
printf("Please enter then number of columns of the first matrix: ");
scanf("%d", &n);
if(n>3){
matrixerror();
}
printf("Please enter the number of rows of the second matrix: ");//Matrix 2
scanf("%d", &p);
if(p>3){
matrixerror();
}
printf("Please enter then number of columns of the second matrix: ");
scanf("%d", &q);
if(q>3){
matrixerror();
}
printf("\nPlease enter the elements of the first matrix:\n");
for(c=0; c<m; ++c)
for(d=0; d<n; ++d){
printf("Enter element a%d%d: ",c+1, d+1);
scanf("%d", &first[c][d]);
}
printf("\nPlease enter the elements of the second matrix:\n");
for(c=0; c<p; ++c)
for(d=0; d<q; ++d){
printf("Enter element b%d%d: ",c+1, d+1);
scanf("%d", &second[c][d]);
}
matrixmenu();
}
and the other one for the operations
void matrixmenu(){
system("CLS");
char choice;
printf("/-----------------------------------------------------------------------------/\n"
"\t\t\t\tMatrix\n"
"/-----------------------------------------------------------------------------/\n");
printf("\n"
"\t1. Add Matrices\n"
"\t2. Multiply Matrices\n"
"\t3. Transpose \n"
"\tB. Back \n");
printf("\n\tFirst matrix is : \n\t");
for(a=0; a<m; ++a)
for(b=0; b<n; ++b){
printf("%d ", first[a][b]);
if (b == n-1)
printf("\n\n\t");
}
printf("\n\tSecond matrix is : \n\t");
for(a=0; a<m; ++a)
for(b=0; b<n; ++b){
printf("%d ", second[a][b]);
if (b == n-1)
printf("\n\n\t");
}
printf("\n");
printf("/------------------------------------------------------------------------------/ ");
scanf("%s", &choice);
switch(choice){
case '1':
printf("\n\tThe sum of entered matrices is: \n\t");
for (a = 0; a < m; a++){
for (b = 0 ; b < n; b++){
msum[a][b] = first[a][b] + second[a][b];
printf("%d\t", msum[a][b]);
}
printf("\n\t");
}
printf("\n\t");
system("PAUSE");
matrixmenu();
break;
case '2':
if (n != p){
printf("\n\tError! Matrix cannot be multiplied!\n\t");
system("PAUSE");
matrixmenu();
}
for (c = 0; c < m; c++){
for (d = 0; d < q; d++){
for (k = 0; k < p; k++){
s = s + first[c][k]*second[k][d];
}
prod[c][d] = s;
s = 0;
}
}
printf("\n\tThe product matrix is:\n\t");
for (c = 0; c < m; c++){
for (d = 0; d < q; d++){
printf("%d\t", prod[c][d]);
}
printf("\n\t");
}
printf("\n\t");
system("PAUSE");
matrixmenu();
break;
case '3':
for(a=0; a<m; ++a)//Tranposition
for(b=0; b<n; ++b)
firstt[b][a] = first[a][b];
printf("\n\tThe transpose of the first matrix is:\n\t");
for(a=0; a<n; ++a)
for(b=0; b<m; ++b){
printf("%d ",firstt[a][b]);
if(b==m-1)
used printf("\n\n\t");
}
for(a=0; a<p; ++a)//Tranposition
for(b=0; b<q; ++b)
secondt[b][a] = second[a][b];
printf("\n\tThe transpose of the second matrix is:\n\t");
for(a=0; a<n; ++a)
for(b=0; b<m; ++b){
printf("%d ",secondt[a][b]);
if(b==m-1)
printf("\n\n\t");
}
printf("\n\t");
system("PAUSE");
matrixmenu();
break;
case 'B':
case 'b':
mainmenu();
break;
default:
matrixmenu();
break;
}
}

You Can Pass Address of variable to function in which you want to work with that variable .
Let us take an example , suppose
#include<stdio.h>
void testing(int *);
int main(){
int x = 3;
printf("%d\n" , x);
testing(&x);
printf("%d" , x);
}
void testing(int *j){
*j = 8;
}
Output Would Be 3 8 , now x is changed in caller function because you passed the address of x (&x) to the function testing and by using *j you are dereferencing that address and storing 8 in the address that j is pointing to , so in effect x changes because you stored its address in a pointer that now points to that address and then you passed that address to other function and where you dereferenced that address (Dereferencing a pointer means getting the value that is stored in the memory location pointed by the pointer. The operator * is used to do this, and is called the dereferencing operator) and changed the value that is stored .
For More Information Look At This Question What does "dereferencing" a pointer mean?

Arrays can be passed as arguments to functions; the function will receive just a pointer to the first element, which you will then be able to index like the original array. The first element of a two-dimensional matrix is a one-dimensional matrix;
Typically, the size of the array must be provided as well, as an integer.
In your case the sizes are known and constant (MAX), but you need 2 "sizes", i.e. the number of rows and columns, per matrix anyway. You can simply pass them on as well.
The program below demonstrates passing a standard array, and additionally presents a feature of modern C, variable length arrays.
#include<stdio.h>
#define MAX 100
// Pass a matrix with constant number of columns
// known at compile time, and the number of columns
// and rows we actually use.
// Both declarations are ok. The first index is ignored.
//void print(int mat[MAX][MAX])
void print(int mat[][MAX], int usedRows, int usedCols)
{
for(int row=0; row<MAX && row<usedRows; row++)
{
for(int col=0; col<MAX && col<usedCols; col++)
{
printf("%5d", mat[row][col]);
}
printf("\n");
}
}
// Pass a variable length array, together with its
// dimensions. Both declarations are ok.
// void printVar(int rows, int cols, int vm[rows][cols])
void printVar(int rows, int cols, int vm[][cols])
{
// demonstrate run-time sizeof(vm[row]).
// one could use the sizeof construct instead of cols.
printf("vla row length is %zd (cols: %d)\n",
sizeof(vm[0])/sizeof(int), cols);
for(int row=0; row<rows; row++)
{
for(int col=0; col<cols; col++)
{
printf("%5d", vm[row][col]);
}
printf("\n");
}
}
int main()
{
// matrix size known at compile time;
// we fill only the first 3 rows and columns.
int m[MAX][MAX]
= {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// print the compile-time sized matrix. Function needs to know
// how many rows and columns we actually used.
print(m, 3, 3);
// Now use a feature of modern C: variable length arrays.
{
int numRows, numCols;
printf("Now variable length array: ");
printf("Please input two numbers, num rows and num columns: ");
if( scanf("%d %d", &numRows, &numCols) != 2)
{
fprintf(stderr, "input error, aborting\n");
return 1;
}
// now define the matrix with the size the user requested.
int varMat[numRows][numCols];
// fill it with some data (cannot hard code, becase I
// don't know the dimensions!)
for(int row=0; row<numRows; row++)
{
for(int col = 0; col < numCols; col++)
{
varMat[row][col] = row * numCols + col + 1;
}
}
// And use the function for variable length array to print.
printVar(numRows, numCols, varMat);
}
return 0;
}
Sample session:
$ gcc -std=c11 -Wall -o matrixfuncs matrixfuncs.c && ./matrixfuncs
1 2 3
4 5 6
7 8 9
Now variable length array: Please input two numbers, num rows and num columns: 2 7
vla row length is 7 (cols: 7)
1 2 3 4 5 6 7
8 9 10 11 12 13 14
A nicer solution would be to define a struct holding a pointer to such a matrix and the two numbers in a single piece of data which can easier be copied around, but I must assume that structs will be covered after arrays in your course.

Related

C Programming How to get results of an mathematical operation stored in a different array?

I am trying to subtract a given number from an array and then store the results in a completely different array. Is it possible to write the code without using pointers?
I am trying to write the code with using for loop and or do/while loop.
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int main(){
int num[100];
int i ;
int size;
int sub;
int diff[100];
printf("Enter the size of the array: ");
scanf("%d", &size);
for(i=0;i<size; i++){
printf("Enter the element %d :", i+1);
scanf("%d", &num[i]);
}
printf(" Enter the number to substract: \n");
scanf("%d", &sub);
for (i=0;i<size; i++)
{
y = num[i]- sub;
scanf("%d", &diff[y]);
}
for (y=0; y<size; y++)
{
printf("%d", diff[y]);
}
}
After I scan the results, I tried different ways to initialize and store the values in the second array but haven't been successful. What mistake am I making here?
y = num[i] - sub;
This is fine, as it's the result of subtraction for a given source array element.
scanf("%d", &diff[y]);
This doesn't make sense, as it's attempting to read input from the user. Not only that, it's using the result of the subtraction as the index of the destination array.
Just assign the result of the subtraction to the corresponding destination array member:
diff[i] = num[i] - sub;
In your question, you try to scan the value to another array, but the correct form is to assign the value in the new array position.
For example, in your first for loop use the i variable as the position and assign num[i] - sub on diff[i]:
for (i = 0; i < size; i++)
{
diff[i] = num[i] - sub;
}
instead of:
for (i=0;i<size; i++)
{
y = num[i]- sub;
scanf("%d", &diff[y]);
}

Reading and Printing a matrix

I tried to read and print a matrix using an external function (from another c file), the thing is that I want to read the matrix dimensions in the function and store them in the main function, how can I do this?
Do I need to return an array with the m and n dimensions of the matrix or can I access the variables that I created in main and change their value within the external function? (I prefer if someone would explain the second) I don't actually know how to use pointers and stuff.
Sorry for my English, I'm not a native speaker, also thanks for your response
The second and the third functions are in an external function.c file
int main(){
int num_of_rows, num_of_columns;
int matrix[10][10];
read_matrix(num_of_rows, num_of_columns, matrix);
print_matrix(num_of_rows, num_of_columns, matrix);
printf("\n Press any key to exit the program: ");
_getch();
return 0;
}
void read_matrix(int num_of_rows, int num_of_columns, int matrix[10][10]){
int i,j;
printf("\nPlease specify the number of rows:");
scanf("%d", &num_of_rows);
printf("\nPlease specify the number of columns: ");
scanf("%d", &num_of_columns);
printf("\nPlease introduce the matrix elements below:\n");
for(i=0; i<num_of_rows; i++){
for(j=0; j<num_of_columns; j++){
printf("matrix[%d][%d]= ", i, j);
scanf("%d", &matrix[i][j]);
}
}
}
void print_matrix(int num_of_rows, int num_of_columns, int matrix[10][10]){
int i,j;
for(i=0; i<num_of_rows; i++){
for(j=0; j<num_of_columns; j++){
printf("matrix[%d][%d]= %d", i, j, matrix[i][j]);
}
}
}
Parameters are passed by value in C.
In read_matrix, the num_of_rows parameter is a local variable. Even if you modify it, the caller won't see anything change. Same for num_of_columns.
You want this:
void read_matrix(int *num_of_rows, int *num_of_columns, int matrix[10][10]) {
// ^ add * ^ add *
...
scanf("%d", num_of_rows); // << remove the &
printf("\nPlease specify the number of columns: ");
scanf("%d", num_of_columns); // << remove the &
...
for (i = 0; i < *num_of_rows; i++) {
// ^add *
for (j = 0; j < *num_of_columns; j++) {
// ^add *
and in main:
read_matrix(&num_of_rows, &num_of_columns, matrix);
// ^ ^ add the &s
This is basic knowledge that is covered in your C learning material. Most likely in the chapter dealing with pointers and the one dealing with function calls.
Here's the catch. I tested your code and it works nicely. The problem is, what you want to achieve is only possible by using dynamic memory allocation. Take a look at the malloc and free functions.
You can read more about it on:
https://www.tutorialspoint.com/what-is-malloc-in-c-language
https://www.tutorialspoint.com/how-do-malloc-and-free-work-in-c-cplusplus
In C language you are responsible for allocation a space in memory for variable length data structures. Pointers just store an address to a specific memory space allocated to the desired data type.
e.g.:
int n, *p;
p = (int*) malloc(n * sizeof(int));
In this example, you are just giving p an address to the first integer from n integers you just allocated.
p will work just like a vector when using for loops because behind the scenes, it's exactly what happens when you traverse your fixed length vectors and matrices, but this time you were in control of it's length in runtime.
#include<stdio.h>
void main()
{
int x[3][3], p, q, max;
printf("Enter the elements of matrix: \n");
for(p=0;p<3;p++)
{
for(q=0;q<3;q++)
scanf("%d", &x[p][q]);
}
max=x[0][0];
printf("The matrix is as follows: \n");
for(p=0;p<3;p++)
{
for(q=0;q<=3;q++)
scanf(" %d", &x[p][q]);
}
for(p=0;p<3;p++)
{
for(q=0;q<3;q++)
{
if(x[p][q]>max)
max=x[p][q];
}
printf("\n");
}
printf("Maximum number in the matrix is: %d", max);
}
Output:
Enter the elements of matrix:
23 65 12
12 23 56
12 10 32
The matrix is as follows:
23 65 12
12 23 56
12 10 32
Maximum number in the matrix is: 65
Matrix Programs
Explore more matrix programs.

transpose square matrix with pointer in C. wrong output

The goal is to print the transpose of the 'Matrix'.
To create square matrix, I got 'row' from the keyboard.
row is same with column so I only declared 'row'.
the problem I need help is right below ↓
/*input*/
5 4 1
9 0 1
6 5 7
/*output I want*/
5 9 6
4 0 5
1 1 7
/*wrong output I get*/
0 4 -30838770
0 7 2
0 5 7
And here is my code. Matrix in each function must be called by reference. I also want to know if I got it right.
//code start
int Generate(int row, int (*Matrix)[row])
{
srand(time(NULL)); //make random number
int i, j;
printf("Matrix = ");
for(i=0; i<row; i++){
for(j=0; j<row; j++){
Matrix[i][j] = (rand() % 10); //insert random number from 0 to 10
printf("%d ", Matrix[i][j]); //print matrix before transposing
}
printf("\n");
}
return 0;
}
void Transpose(int row, int (*Matrix)[row])
{
int i, j;
for(i=0; i<row; i++){
for(j=0; j<row; j++){
int transpose[i][j];
transpose[i][j] = Matrix[j][i];
printf("%d ", transpose[i][j]);
}
printf("\n");
}
}
int main() {
int input; //for switch case
int row = 0; //row has to be 2 or 3
int Matrix[row][row]; //2d array. largest index should be Matrix [row-1][row-1]
while(1){
scanf("%d", &input);
switch(input){
case 1: // Generate random square matrix
scanf("%d", &row); //insert row
Generate(row, Matrix);
break;
case 2: //transpose matrix
Transpose(row, Matrix);
break;
default:
return 0;
}
}
}
//code end
I'm new to this community so I'm not sure I gave you all the information needed.
Please let me know the lines you don't understand because I really want to get this code work.
I'm waiting for your help!
Your program is trying to print the transpose, so you don't need to store anything. remove all the stuff with transpose[i][j], and just print Matrix[j][i]. As pointed out in the comments, you are allocating (on the stack) a new matrix of shape ixj at each iteration, which makes no sense.

Sorting inputted integers into odd and even arrays

I'm a beginner to C, and am trying to sort user inputted numbers into odd and even arrays. I don't understand why my code isn't working.
Cheers.
This is my code, I don't understand my mistake.
int x[]= {};
int i=0;
int d=0;
int j=0;
int even[12]={};
int odd[12]={};
printf("Enter amount of numbers: "); // asking user for amount of numbers
scanf("%d", &d);
for (j=0; j<d; j++){
printf("Enter number %d: ", i+1); // scanning input into 'x' array
scanf("%d", x[i]);
}
printf("Even numbers: ");
for (i=0; i<d; i++) {
if (x[i] % 2 == 0) { // sorting into even array
even[i]=x[i];
printf("%d \n", even[i]);
}
}
printf("\n Odd numbers: ");
for (i=0; i<d;i++){
if (x[i] % 2 != 0) { // sorting into odd array
odd[i]=x[i];
printf("%d \n", odd[i]);
}
}
This error message keeps coming up:
$ ./main
Enter amount of numbers: 4
Enter number 1: 6
Segmentation fault (core dumped)
int x[]= {}; doesn't work because it would hold no elements. But initializing it with {} doesn't work in C anyway, do this instead:
int x[24] = {0}; // first element explicitely set to 0, the rest default-initialized to 0
You also need to put {0} for even and odd. If it's compiling for you with {} then it's possible that you're compiling it as a C++ program, or perhaps your compiler just tolerates it anyway (but it won't work on every C compiler).
scanf needs the address of the int, so instead of scanf("%d", x[i]); you need scanf("%d", &x[i]);. But i is the wrong iterator for this for (j = 0; j < d; j++) loop. Instead do this:
for (j = 0; j < d; j++) {
printf("Enter number %d: ", j + 1); // scanning input into 'x' array
scanf("%d", &x[j]);
}
Also note that the way you're doing this, half the array will be left at 0. So for instance if I imputted the values 1 through 6, then odd contains the values 1 0 3 0 5 0.

Fibonacci Series in C Program where FIRST 2 numbers are given by user

When the first number is 1 and second number is 2, and the length is 5, it should be 1 2 3 5 8. But then my output is always 1 2 1 3 4. I can't seem to find the problem.
Another input is 2 and 5. Output is 2 5 1 6 7. The 3rd number which is 1 shouldn't be there. What should I change or add?
*This is already a submitted HW and yes its wrong I got the deductions already. Now I just want to fix this so I can study this.
int main()
{
int i, lenght = 0, fib, sum, sum1, sum2, a, b, c;
printf("\nFirst number: ");
scanf("%d", &a);
printf("\nSecond number: ");
scanf("%d", &b);
printf("\nHow long?: ");
scanf("%d", &lenght);
{
while ((a > b) || ((lenght < 2) || (lenght > 100)))
{
printf("\nFirst number: ");
scanf("%d", &a);
printf("\nSecond number: ");
scanf("%d", &b);
printf("\nHow long?: ");
scanf("%d", &lenght);
}
}
printf("%d\t%d\t", a, b);
printf("%d\t", fib);
for (i = 3; i < lenght; i++) {
if (i <= 1) fib = i;
else {
a = b;
b = fib;
fib = a + b;
}
printf("%d\t", fib);
}
}
The first time you print fib (before the for loop), you haven't assigned it anything yet.
Since this is for study, issues with your code: you don't need to duplicate the calls to scanf(), simply initialize one of the variables to fail (which you did: lenght = 0) and let the loop do its thing; pick one indentation style and stick with it; if you're new to C, always include the curly braces, even when the language says they're optional; you (correctly) allow for a length of 2, but then print three numbers; your if (i <= 1) clause is a no-op as the loop starts with for (i = 3; so i is never less than 3.
Putting it all together, we get something like:
#include <stdio.h>
int main() {
int length = 0, a, b;
while (length < 2 || length > 100 || a > b ) {
printf("\nFirst number: ");
(void) scanf("%d", &a);
printf("\nSecond number: ");
(void) scanf("%d", &b);
printf("\nHow long?: ");
(void) scanf("%d", &length);
}
printf("%d\t%d\t", a, b);
for (int i = 2; i < length; i++) {
int fib = a + b;
printf("%d\t", fib);
a = b;
b = fib;
}
printf("\n");
return 0;
}
Note that the input error checking isn't sufficient to prevent problems. E.g. b can be greater than a, but still mess up the sequence if you input random numbers. You're assuming the user knows to put in two adjacent items from fibonacci sequence which is tricky to test.
just add fib=a+b; before printing fib value.
Its a good coding habit to initialize all variable before using it(especially in C).
Your code seems strange to me. I tried to simplify your code a bit. See this once:
int main()
{
int a,b,next,last,i;
printf("Enter the first Value:");
scanf("%d",&a);
printf("Enter the second Value:");
scanf("%d",&b);
printf("Enter the length of Fab. series:");
scanf("%d",&last);
printf("%d,%d,",a,b);
for (i=3; i<= last; i++)
{
next = a + b;
if(i<last)
printf("%d,",next);
else
printf("%d",next);
a = b;
b = next;
}
return 0;
}
Hope it's Helpful!!

Resources