why my outer loop is not repeating itself? - arrays

#include<stdio.h>
void printarr( int arr , int a,int b){
for(int z=0;z<a;z++){
for(int x=0;x<b;x++){
printf("the marks of student %d in subject %d and %d is :%d\n",z+1 ,
x+1 , x+2 , arr);
}
}
}
int main(){
int n_students = 5;
int n_sub = 2;
int marks[5][2];
for (int i=0; i<n_students; i++){
for (int j=0; j<n_sub; j++){
printf("enter the marks of student %d in subject %d\n", i+1, j+1);
scanf("%d", marks[i][j]);
}
}
printarr(marks , 5 , 2);
return 0;
i am getting to put only two times and the outer loop is not repeating itself
please explain me in simple terms , i am just learning this launguage
complete begineer.

1.When passing two-dimensional arrays, it is not mandatory to specify the number of rows in the array. However, the number of columns should always be specified.
void printarr( int arr , int a,int b){ --->void printarr( int arr [][2], int
a,int b){
2.When reading array element in scanf you have missed &
scanf("%d", marks[i][j]);--->scanf("%d", &marks[i][j]);
3.When Printing array elements in printf you have to specify the index.
arr ---> arr[i][j]
#include<stdio.h>
void printarr( int arr [][2], int a,int b){
for(int z=0;z<a;z++){
for(int x=0;x<b;x++){
printf("the marks of student %d in subject %d is :%d\n",z+1,x+1,arr[z][x]);
}
}
}
int main(){
int n_students = 5;
int n_sub = 2;
int marks[5][2];
for (int i=0; i<n_students; i++){
for (int j=0; j<n_sub; j++){
printf("enter the marks of student %d in subject %d\n", i+1, j+1);
scanf("%d", &marks[i][j]);
}
}
printarr(marks, 5 , 2);
return 0;
}

You want this: (explanation in comments)
#include <stdio.h>
#include<stdio.h>
void printarr(int a, int b, int arr[a][b]) { // pass an array, not an int,
// and a and b must be before arr
for (int z = 0; z < a; z++) {
for (int x = 0; x < b; x++) {
printf("the marks of student %d in subject %d and %d is :%d\n", z + 1,
x + 1, x + 2, arr[z][x]); // use arr[x][z] here. arr obviously dons' make sense
}
}
}
int main() {
int n_students = 5;
int n_sub = 2;
int marks[5][2];
for (int i = 0; i < n_students; i++) {
for (int j = 0; j < n_sub; j++) {
printf("enter the marks of student %d in subject %d\n", i + 1, j + 1);
scanf("%d", &marks[i][j]); // you forgot the &
}
}
printarr(5, 2, marks); // you need to pass the size beforen the array
return 0; // read the documentation about VLAs
}

Related

Error when passing 2D array to function in c

I am writing a program to calculate matrix multiplication but it does not work. When I debug and check each value of the array a and b in function printMatrixMultiplication (which are entered by user), GDB prints out "cannot perform pointer math on incomplete type try casting". (I have searched for it but I still don't get it.) The function only works when the input is predefined in main.
This is my code
#include <stdio.h>
void input(int m, int n, double a[m][n]);
void output(int m, int n, double a[m][n]);
void printMatrixMultiplication(int row_a, int col_a, double a[row_a][col_a], int row_b, int col_b, double b[row_b][col_b]);
int main()
{
int row_a, col_a, row_b, col_b;
// get value of matrix a
printf("row_a = ");
scanf("%d", &row_a);
printf("col_a = ");
scanf("%d", &col_a);
double a[row_a][col_a];
input(row_a, col_a, a);
// output(row_a, col_a, a);
// get value of matrix b
printf("row_b = ");
scanf("%d", &row_b);
printf("col_b = ");
scanf("%d", &col_b);
double b[row_b][col_b];
input(row_b, col_b, a);
// output(row_b, col_b, a);
printMatrixMultiplication(row_a, col_a, a, row_b, col_b, b);
//test
// double a[2][2]={1,2,3,4};
// double b[2][3]={1,2,3,4,5,6};
// printMatrixMultiplication(2,2,a,2,3,b);
return 0;
}
void input(int m, int n, double a[m][n])
{
int i, j;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
scanf("%lf", &a[i][j]);
}
}
}
void output(int m, int n, double a[m][n])
{
int i, j;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
printf("%.2f ", a[i][j]);
}
printf("\n");
}
}
void printMatrixMultiplication(int row_a, int col_a, double a[row_a][col_a], int row_b, int col_b, double b[row_b][col_b])
{
if (col_a != row_b)
{
return;
}
double res[row_a][col_b]; //this matrix store results
for (int i = 0; i < row_a; i++) //the values be stored line by line, this
{ //operation is controled by i and j loops.
for (int j = 0; j < col_b; j++) //the k loop helps calculate dot_product.
{
double dot_product = 0;
for (int k = 0; k < col_a; k++)
{
dot_product += a[i][k] * b[k][j]; //ERROR HERE
}
res[i][j] = dot_product;
}
}
output(row_a, col_b, res);
}
So, where does the error come from and how to fix it?
Irrelevant, but the function is not well implemented so if possible, I would really appreciate if anyone gives me a hint to improve it.
I am using GCC version 6.3.0.
It's typo in your code when reading matrix b.
Just replace:
input(row_b, col_b, a);
with
input(row_b, col_b, b);

C - maximum value from one dimensional array's groups

So, my task is to let user fill one dimensional array A. This array has M number of groups and P members in each group. I need to fill array B with maximum values of each group in A array and display results of maximum values in each group after. I couldn't figure out any way to do it. I would really appreciate your help since I am a beginner programmer and doing my best to study. So my main problem in code is fillBArray function.
#include <stdio.h>
#include <stdlib.h>
int checkingvariable(int k, int a, int b);
void fillArray(int M, int P,int A[]);
void printArray(int M, int P,int A[]);
void fillBArray(int M, int P,int A[]);
int main()
{
int M, P;
printf("Enter M (the number of groups): ");
scanf("%d", &M);
M=checkingvariable(M, 1, 10);
printf("Enter P (the number of cars in one group): ");
scanf("%d", &P);
P=checkingvariable(P, 1, 10);
int i = P*M;
int A[i];
fillArray(M, P, A);
printArray(M, P, A);
fillBArray(M, P, A);
return 0;
}
void printArray(int M, int P,int A[])
{
int i;
for (i=0 ; i< M*P ; i++)
{
printf("%d ", A[i]);
printf("\n");
}
}
void fillArray(int M, int P, int A[])
{
int i;
for (i=0 ; i< M*P ; i++)
{
printf("Enter speed of car %d: ", i+1);
scanf("%d", &A[i]);
}
}
void fillBArray(int M, int P, int A[])
{
int c, k=0;
int maximum = A[0];
int B[M], group;
for (c = 0; c < P*M; c++)
{
if (A[c] > maximum)
{
maximum = A[c];
}
maximum = B[k];
printf("Maximum value for %d group is: %d", group, maximum);
}
}
int checkingvariable(int k, int a, int b)
{
if (k<a || k>b)
{
while(k<a || k>b)
{
printf("Enter correct value between %d and %d: ", a, b);
scanf("%d", &k);
}
}
return k;
}
One way is to replace one loop with two nested loops. The outer loop would iterate groups, while the nested loop would iterate members in each group.
One observation before you begin: members of a group g in the array A are located between indexes g*P, inclusive, and (g+1)*P, exclusive. Member m of a group is located at the index A[g*P + m].
Now it should be clear how to make your loops:
for (int g = 0 ; g != M ; g++) { // Groups
int max = A[g*P];
for (int m = 1 ; m != P ; m++) { // Members
... // Compute max
}
// Store max for group g in B[]
}
#include <stdio.h>
#include <stdlib.h>
int checkingvariable(int k, int a, int b);
void fillArray(int M, int P,int A[]);
void printArray(int M, int P,int A[]);
void fillBArray(int M, int P,int A[]);
int main()
{
int M, P;
printf("Enter M (the number of groups): ");
scanf("%d", &M);
M=checkingvariable(M, 1, 10);
printf("Enter P (the number of cars in one group): ");
scanf("%d", &P);
P=checkingvariable(P, 1, 10);
int i = P*M;
int A[i];
fillArray(M, P, A);
printArray(M, P, A);
fillBArray(M, P, A);
return 0;
}
void printArray(int M, int P,int A[])
{
int i;
for (i=0 ; i< M*P ; i++)
{
printf("%d ", A[i]);
printf("\n");
}
}
void fillArray(int M, int P, int A[])
{
int i;
for (i=0 ; i< M*P ; i++)
{
printf("Enter speed of car %d: ", i+1);
scanf("%d", &A[i]);
}
}
/*void fillBArray(int M, int P, int A[])
{
int c, k=0;
int maximum = A[0];
int B[M], group;
for (c = 0; c < P; c++)
{
if (A[c] > maximum)
{
maximum = A[c];
}
if (c < P)
{
group = 1;
maximum = A[c];
printf("Maximum value for %d group is: %d", group, maximum);
}
if (c < P*2)
{
group = 2;
k=1;
maximum = A[c];
printf("Maximum value for %d group is: %d", group, maximum);
}
}
}*/
void fillBArray(int M, int P, int A[])
{
int B[M], maximum = 0, m;
for (int g = 0 ; g != M ; g++)// Groups
{
int max = A[g*P];
for (m = 0 ; m != P ; m++) // Members
{
if (A[g*P + m] > maximum)
{
maximum = A[g*P + m];
}
}
B[g] = maximum;
printf("Maximum value for %d group is: %d", g+1, maximum);
printf("\n");
maximum = 0;
}
}
int checkingvariable(int k, int a, int b)
{
if (k<a || k>b)
{
while(k<a || k>b)
{
printf("Enter correct value between %d and %d: ", a, b);
scanf("%d", &k);
}
}
return k;
}
This is answer to my problem, check fillBArray.

Using scanf() with a pointer to a double pointer

I feel like I've attempted every combination I know of to get this to work and can't figure it out. How can I scanf() into an int** passed as a pointer to a function? I tried searching but couldn't find this, if it's a duplicate please let me know and I'll delete. It begins to run and after entering a few values it segfaults.
Here's my code, I think it's messing up on the scanf() line of the setMatrix() function:
#include <stdio.h>
#include <stdlib.h>
// create zero initialized matrix
int** callocMatrix(int rmax, int colmax) {
int **mat = calloc(rmax, sizeof(int*));
for(int i = 0; i < rmax; i++) mat[i] = calloc(colmax, sizeof(int));
return mat;
}
// fill matrix
void setMatrix(int ***mat, int r, int c){
printf("Insert the elements of your matrix:\n");
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
printf("Insert element [%d][%d]: ", i, j);
scanf("%d", mat[i][j]); // problem here??
printf("matrix[%d][%d]: %d\n", i, j, (*mat)[i][j]);
}
}
return;
}
// print matrix
void printMatrix(int ***mat, int r, int c){
for (int i=0; i<r;i++){
for (int j=0; j<c;j++) {
printf("%d ", (*mat)[i][j]);
}
printf("\n");
}
}
int main(int argc, char *argv[]) {
int r = 3, c = 3;
int **mat = callocMatrix(r, c);
setMatrix(&mat, r, c);
printMatrix(&mat, r, c);
}
There is no need to use triple pointer ***. Passing two-dimensional array will work as is. Here is the code:
#include <stdio.h>
#include <stdlib.h>
// create zero initialized matrix
int** callocMatrix(int rmax, int colmax) {
int **mat = calloc(rmax, sizeof(int*));
for(int i = 0; i < rmax; i++) mat[i] = calloc(colmax, sizeof(int));
return mat;
}
// fill matrix
void setMatrix(int **mat, int r, int c){
printf("Insert the elements of your matrix:\n");
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
printf("Insert element [%d][%d]: ", i, j);
scanf("%d", &mat[i][j]); // no problem here
printf("matrix[%d][%d]: %d\n", i, j, mat[i][j]);
}
}
}
// print matrix
void printMatrix(int **mat, int r, int c){
for (int i=0; i<r;i++){
for (int j=0; j<c;j++) {
printf("%d ", mat[i][j]);
}
printf("\n");
}
}
int main(int argc, char *argv[]) {
int r = 3, c = 3;
int **mat = callocMatrix(r, c);
setMatrix(mat, r, c);
printMatrix(mat, r, c);
}
Should be:
scanf("%d", &(*mat)[i][j]);
You're passing a pointer to you matrix object, so you need to dereference it (with *) just as you do with printf. scanf then needs the address of the element to write into, so you need the &

Find point with two-dimensional dynamic array in C

Given m points in the plane. Number of xy coordinates must be
entered via the keyboard. How to find this coordinates from xy? With two-dimensional dynamic array.
Now I have this but it's not working:
int **enterPoints (int m) {
int i, **points;
scanf("%d",&m);
points = (int **)malloc(m*sizeof(int *));
if (points != NULL) {
for (i=0; i<m; i++) {
*(points+i) = (int *)malloc(m*sizeof(int));
if (*(points+i)==NULL)
break;
}
{
printf("enter %d points coord X and Y:", i+1);
scanf("%d %d", &*(*(points+i)+0), &*(*(points+i)+1));
*(*(points+i)+2)=0;
}
}
free(points);
return points;
}
try this
#include <stdio.h>
#include <stdlib.h>
int **enterPoints (int m){
int i, **points;
//scanf("%d",&m);//already get as argument
if(m<=0)
return NULL;
points = (int**)malloc(m*sizeof(int*));
if (points != NULL){
for (i=0; i<m; i++){
points[i] = (int*)malloc(2*sizeof(int));
if(points[i]!=NULL){
printf("enter %d points coord X and Y:", i+1);fflush(stdout);
scanf("%d %d", &points[i][0],&points[i][1]);
}
}
}
//free(points);//free'd regions is unusable
return points;
}
int main(void){
//test code
int i, m, **points;
//scanf("%d", &m);
m = 3;
points = enterPoints(m);
for(i = 0; i < m; ++i){
printf("(%d, %d)\n", points[i][0], points[i][1]);
free(points[i]);
}
free(points);
return 0;
}

how to store multiple arrays and make array of pointers to them

I don't have a lot of experience with pointers, but I want to try to make an array of pointers, each pointer pointing to a scanned string.
For example, you first input how many strings you want to scan (for example 5), and then I want to scan those strings and make an array of 5 pointers that point to those strings.
Because I didn't have a lot experience with something like this, I first tried it with normal arrays instead of strings, what I got is this:
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<assert.h>
int **array(int m, int n) {
int i, j;
int **array = malloc(n*sizeof(int*));
for (j=0; j<m; j++) {
for (i=0; i<n; i++) {
array[i]=malloc(m * sizeof(int));
scanf("%d", &array[j][i]);
printf("array[%d][%d] is scanned and has value %d\n", j, i, array[j][i]);
}
}
return array;
}
int main(int argc, char*argv[]){
int m, n, *p, k;
scanf("%d %d", &m, &n);
printf("m is %d and n is %d\n", m, n);
p=*array(m, n);
printf("the numbers are:\n");
for (k=0; k<m*n; k++) {
printf("%d\n", p[k]);
}
return 0;
}
But here it's already going wrong, and I don't know why...
At the last printf, I always get wrong numbers, 0's and 17's...
Can someone explain me why this is and what I'm doing wrong? I think it's something with the returning of the array but I'm not sure..
If someone could explain this to me it would be great.
The problem with your code is the following:
// m = 3, n = 5
// array = ptr1, ptr2, ptr3, ptr4, ptr5
// | |
// 3 ints |
// 3 ints ..
int **array(int m, int n) {
int i, j;
int **array = (int**)malloc(n*sizeof(int*));
for (j=0; j<m; j++) {
for (i=0; i<n; i++) {
array[i]=(int*)malloc(m * sizeof(int));
scanf("%d", &array[j][i]);
printf("array[%d][%d] is scanned and has value %d\n", j, i, array[j][i]);
}
}
return array;
}
In the above example (m=3, n=5) you allocated 5 pointers to integers and then tried to populate them by allocating memory at each iteration in the inner-loop (WRONG). If you allocate new memory at each iteration, you're gonna lose the pointer to the previously allocated memory and the data you stored!
Plus the indices seem to be wrong for the inner and outer loop, a correct version of your code is:
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<assert.h>
// 3, 5
// array = ptr1, ptr2, ptr3, ptr4, ptr5
// | |
// 3 ints |
// 3 ints ..
int **array(int m, int n) {
int i, j, index;
int **array = (int**)malloc(n*sizeof(int*));
index = 0;
for (j=0; j<n; j++) {
array[j]=(int*)malloc(m * sizeof(int)); // Allocate once per each j
for (i=0; i<m; i++) {
array[j][i] = index++;
printf("array[%d][%d] is scanned and has value %d\n", j, i, array[j][i]);
}
}
return array;
}
int main(int argc, char*argv[]){
int m, n, **p, k, i, j;
m = 3;
n = 5;
printf("m is %d and n is %d\n", m, n);
p=array(m, n);
printf("the numbers are:\n");
for (j=0; j<n; j++)
for(i=0; i<m; i++)
printf("%d\n", p[j][i]);
return 0;
}
And the above version is STILL NOT CORRECT : You need to free the allocated memory!
I'll leave that as an exercise.. hint: you CAN'T simply do "free(p);" :]
Are you sure about this for loop? If you've the malloc inside the inner loop you're not creating a matrix because every time you override the same cells...
int i, j;
int **array = malloc(n*sizeof(int*));
for (j=0; j<m; j++) {
for (i=0; i<n; i++) {
array[i]=malloc(m * sizeof(int));
scanf("%d", &array[j][i]);
printf("array[%d][%d] is scanned and has value %d\n", j, i, array[j][i]);
}
}
It should be something like:
int i, j;
int **array = malloc(n*sizeof(int*));
for (i=0; i<n; i++) {
array[i]=malloc(m * sizeof(int));
for (j=0; j<m; j++) {
scanf("%d", &array[i][j]);
printf("array[%d][%d] is scanned and has value %d\n", i, j, array[i][j]);
}
}
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<assert.h>
void *array(int m, int n) {
int i, j;
int (*array)[n] = malloc(sizeof(int [m][n]));//m*n*sizeof(int)
for (j=0; j<m; j++) {
for (i=0; i<n; i++) {
scanf("%d", &array[j][i]);
printf("array[%d][%d] is scanned and has value %d\n", j, i, array[j][i]);
}
}
return array;
}
int main(int argc, char*argv[]){
int m, n, *p, k;
scanf("%d %d", &m, &n);
printf("m is %d and n is %d\n", m, n);
p=(int*)array(m, n);
printf("the numbers are:\n");
for (k=0; k<m*n; k++) {
printf("%d\n", p[k]);
}
return 0;
}
#include <stdlib.h>
#include <stdio.h>
char **array(int m, int n) {
int i;
char **array = malloc(m*sizeof(char*));
for (i=0; i<m; ++i) {
array[i] = malloc(n*sizeof(char));//Fixed length : like char array[m][n] (char *array[m])
scanf("%s", array[i]);//!! There is no length constraints.
printf("array[%d] is scanned and has value %s\n", i, array[i]);
}
return array;
}
int main(int argc, char*argv[]){
int m, n, k;
char **p;
scanf("%d %d", &m, &n);
printf("m is %d and n is %d\n", m, n);
p=array(m, n);
printf("the string are:\n");
for (k=0; k<m; ++k) {
printf("%s\n", p[k]);
}
return 0;
}
I'm not sure if I do this smart, but I usually allocate the pointer array and then allocate the whole memory chunk to the first item. Then I get continuous memory for the data. Like:
_array = (float**) malloc( n * sizeof ( float * ));
assert ( _array != NULL );
_array[0] = (float*) malloc( n * m * sizeof ( float ));
assert ( _array[0] != NULL );
for ( idx = 0; idx < n; idx++ )
_array[ idx ] = _array[ 0 ] + idx * m;
(float instead of int in my case. And please don't comment on the return of malloc casting, nor on the silly user of assert())

Resources