What I'm trying to do is find a way to add extra elements to the already hardcoded int array matrix. Here is my current code:
#include <stdio.h>
int main(){
int matrix[25] = {2,3};
int i;
int j;
for(i=4,j=2; i<21 && j<17; i++,j++){
matrix[j] = i;
}
printf("%d", matrix);
}
I'm not sure what went wrong here.
You can't print array elements with integer type specifier %d. You need to iterate through the array elements using a loop such as for and then print each element.
for(int x=0; x < 17; x++) {
printf("%d", matrix[x]);
}
You are giving to print directly matrix but it will show a warning like this
warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat=]
this is because when you give only matrix without indexes([]) or '*' it prints garbage value so you can use loops for printing a matrix
for(int i=0; i < 17; i++)
printf("%d", matrix[i]);
OR
for(int i=0; i < 17; i++)
printf("%d ", *(matrix+i));
Peace!
Happy Coding!
int main()
{
int r = 3, c = 4;
int *arr = (int *)malloc(r * c * sizeof(int));
int i, j, count = 0;
for (i = 0; i < r; i++) *emphasized text*
for (j = 0; j < c; j++)
*(arr + i*c + j) = ++count;
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
printf("%d ", *(arr + i*c + j));
Use can use malloc to to create dynamic array. by using the malloc if the size of the array is full you can reallocate the array by using the malloc function. The malloc will copy the previous array in the new array with the new size.
Related
I've gotten back into C recently after a long absence, and I can't for the life of me remember how to pass a 2D matrix to a function and use it after mallocating it. I believe I've passed the pointer correctly, but I can't seem to actually access anything in the matrix and can't figure out why.
This is what I have written:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
void matrixOperation(int *arr, int m, int n)
{
printf("in matrixOperation\n ");
int i, j;
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
printf("%d\n", *((arr+i*n) + j));
}
int main()
{
int i,j,count;
int row, col;
//------------------------------
printf("Number of rows?\n ");
scanf("%d", &row);
printf("Number of columns?\n ");
scanf("%d", &col);
//------------------------------
int* arr[row];
for (i = 0; i < row; i++)
arr[i] = (int*)malloc(col * sizeof(int));
count = 0;
for (i = 0; i < row; i++)
for (j = 0; j < col; j++)
arr[i][j] = ++count;
for (i = 0; i < row; i++)
for (j = 0; j < col; j++)
printf("%d\n",arr[i][j]);
// We can also use "print(&arr[0][0], m, n);"
matrixOperation((int *)arr, row, col);
for (int i = 0; i < row; i++)
free(arr[i]);
return 0;
}
The goal was to have it accept user input for the size of the matrix, fill each index with a count and then pass it to a function which would print it out. However when I try it the print statement just outputs random numbers which I assume are what the pointers are pointing at.
I would like matrixOperation to print out the same thing as the print statement in main and I can't quite figure out what I've done wrong.
Change the function signature and you should be able to use the same piece of code.
void matrixOperation(int **arr, int m, int n)
{
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
printf("%d\n",arr[i][j]);
}
Call with:
matrixOperation(arr, row, col);
Remember when an array is passed to a function, it "decays" into a pointer. You have an array of pointers. That decays to a pointer to pointers.
You declared an array of pointers:
int* arr[row];
So pass this array to the function.
The function will be declared like:
void matrixOperation(int **arr, int m, int n)
{
printf("in matrixOperation\n ");
int i, j;
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
printf("%d\n", *( *( arr + i ) + j ) );
}
and call the function like:
matrixOperation( arr, row, col );
Though it will be better to define the function like:
void matrixOperation(int **arr, int m, int n)
{
printf("in matrixOperation\n ");
for ( int i = 0; i < m; i++ )
{
for ( int j = 0; j < n; j++ )
{
printf("%d ", *( *( arr + i ) + j ) );
}
putchar( '\n' );
}
}
Pay attention to that this expression with the pointer arithmetic:
*( *( arr + i ) + j )
can be rewritten using the subscript operator the following way:
arr[i][j]
The both expressions are equivalent each other.
As for your call of the function with casting the array designator:
matrixOperation((int *)arr, row, col);
then it is wrong because you do not have one extent of memory. You allocated several extents of memory.
int main()
{
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
int rslt, n;
float sum = 0;
scanf("%d", &n);
int *tri = (int*)malloc(n * 3 * sizeof(int));
if(tri == NULL){
return 1;
}
printf("%d\n", *(tri[0]));
when I am referencing the tri pointer then it is showing the error.
invalid type argument of unary '*'.
thanks for the answer.
The above part is clarified but I have another issue. but I have another issue
int main()
{
int rslt, n;
float sum = 0;
scanf("%d", &n);
int *tri = (int*)malloc(n * 3 * sizeof(int));
if(tri == NULL){
return 1;
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < 3; j++)
{
scanf("%d", &(tri[j]));
}
printf("\n");
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < 3; j++)
{
sum += tri[j] / 2;
printf("%d %d\n",sum,tri[j] / 2);
}
}
printf("%d\n",sum);
return 0;
}
when I am printing the tri[j] it is showing some garbage value.
The variable tri has the type int * due to this declaration
int *tri = (int*)malloc(n * 3 * sizeof(int));
Pay attention to that you allocated an uninitialized memory.
The expression tri[0] has the type int. And you are trying to apply the dereference operator to the expression of the type int
*(tri[0])
So the compiler issues an error.
Instead you could write
int *tri = (int*)calloc(1, n * 3 * sizeof(int));
and then write either
printf("%d\n", tri[0]);
or
printf("%d\n", *tri);
These for loops
for (int i = 0; i < n; i++)
{
for (int j = 0; j < 3; j++)
{
scanf("%d", &(tri[j]));
}
printf("\n");
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < 3; j++)
{
sum += tri[j] / 2;
printf("%d %d\n",sum, tri[j] / 2);
}
}
printf("%d\n",sum);
are incorrect. There are used an incorrect conversion specifier %d instead of %f with the variable sum and incorrect expressions for indices. You need to write
for (int i = 0; i < n; i++)
{
for (int j = 0; j < 3; j++)
{
scanf("%d", &(tri[3 * i + j]));
}
printf("\n");
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < 3; j++)
{
sum += tri[3 * i + j] / 2;
printf("%f %d\n",sum, tri[3 * i + j] / 2);
}
}
printf("%f\n",sum);
The array expression a[i] is defined as *(a + i) - given some address value a, offset i elements (not bytes!) from that address and dereference the result, so
*tri == *(tri + 0) == tri[0]
The expression tri[0] has type int, which is why the compiler is complaining when you write *(tri[0]); the operand of the unary * operator must have a pointer type.
So in your printf statement you would use either *tri or tri[0]. The type of either expression is int.
As others have said, malloc does not initialize the allocated memory, so the value of tri[0] may be anything. You could use calloc instead, which initializes the memory to all-bits-zero:
int *tri = calloc( n, sizeof *tri );
In C you do not need to cast the result of malloc, calloc, and realloc1, and most of us will advise you to not do so. Similarly, since the type of the expression *tri is int, the result of sizeof *tri is the same as sizeof (int). This way you don't have to worry about keeping types straight between the declaration, the cast, and the sizeof expression, so you're less likely to make a mistake.
This is not the case in C++, but if you're writing C++ you shouldn't be using the C *alloc functions anyway.
I am relatively new to c, and I still have not been able to find a good way of passing and returning a multi-dimensional array from a function. I found the following code, however it doesn't seem like a good way to do things because it passes the array and then to use it, it creates a duplicate with the malloc function. Is there a way to do it without the copying and malloc function, or a better way to pass and return an 2d array from a function in c in general? Thanks.
#include <stdio.h>
#include <stdlib.h>
int **matrix_sum(int matrix1[][3], int matrix2[][3]){
int i, j;
int **matrix3;
matrix3 = malloc(sizeof(int*) * 3);
for(i = 0; i < 3; i++) {
matrix3[i] = malloc(sizeof(int*) * 3);
}
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
matrix3[i][j] = matrix1[i][j] + matrix2[i][j];
}
}
return matrix3;
}
int main(){
int x[3][3], y[3][3];
int **a;
int i,j;
printf("Enter the matrix1: \n");
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
scanf("%d",&x[i][j]);
}
}
printf("Enter the matrix2: \n");
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
scanf("%d",&y[i][j]);
}
}
a = matrix_sum(x,y); //asigning
printf("The sum of the matrix is: \n");
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
printf("%d",a[i][j]);
printf("\t");
}
printf("\n");
}
//free the memory
for(i = 0; i < 3; i++) {
free(a[i]);
}
free(a);
return 0;
}
The array are not copied for agurments. Just pointers to the first elements of them (int[3]) are passed.
To avoid malloc(), you should add another argument to specify the array where the result should be stored.
#include <stdio.h>
void matrix_sum(int matrix3[][3], int matrix1[][3], int matrix2[][3]){
int i, j;
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
matrix3[i][j] = matrix1[i][j] + matrix2[i][j];
}
}
}
int main(){
int x[3][3], y[3][3], a[3][3];
int i,j;
printf("Enter the matrix1: \n");
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
scanf("%d",&x[i][j]);
}
}
printf("Enter the matrix2: \n");
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
scanf("%d",&y[i][j]);
}
}
matrix_sum(a,x,y);
printf("The sum of the matrix is: \n");
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
printf("%d",a[i][j]);
printf("\t");
}
printf("\n");
}
return 0;
}
An array can be declared and used through a reference (pointer)
for instance
char array[] = {'h','e','l', 'l', 'o', '\0'};
char *pointer = array;
the way pointers work can be understood by calling sizeof() on a given type
printf("char:%d\nchar_pointer: %d\n", sizeof(char), sizeof(char*));
which results in the following output.
char:1
char_pointer: 4
these results mean that even though a char has 1byte, its pointer needs 4 in order to be stored in memory thus, they are not the same type.
now in order to pass an array as an argument to a function you have many options
void function1(array[4])
{
//this function can receive an array of four elements and only four elements;
//these types of functions are useful if the algorithm inside the function only works
//with a given size. e.g. matrix multiplication
}
//or
void function2(char array[], int size)
{
//this function can receive an array of elements of unknown size, but you can
//circumvent this by also giving the second argument, the size.
int i;
for(i = 0; i <= size; i++)
{
printf("%c", array[i]);
}
}
In order to use or call any of these functions you could pass the array or a pointer to the array
function2(array, 5);
function2(pointer, 5);
//these results are the same
The same applies to a multidimensional array
void function3(char** multi_dim_array, array_size_first_dim, array_size_second_dim);
//and you can call it by using the same syntax as before;
void main(int argc, char[] argv*)
{
char** multi_dim = malloc(sizeof(char*) * 3);
int i;
for(i = 0; i<=3 ; i++)
{
multi_dim[i] = malloc(sizeof(char) * 4);
}
function3(multi_dim, 3,4);
}
if you want to return a multidimensional array you can just return a pointer
char **malloc_2d_array(int dim1, int dim2)
{
char ** array = malloc(sizeof(char*)*dim1);
int i;
for(i = 0; i<=dim2; i++)
{
array[i] = malloc(sizeof(char) * dim2);
}
return array;
}
as a final note, the reason the code you found, copies the array, is because of functional programming(a way of programming if you will) where a function call cant modify its input, thus it will always create a new value;
First of all this is not gonna be a technical explanation. I am just gonna try and explain what works not why.
For passing a multidimensional array you can use either an array with a defined size as you did in your example code:
void matrix_sum(int matrix3[][3])
Or if you don't want to use a defined size and want to take care of memory usage you can use a pointer to a pointer. For this case you also need to pass the size (unless you are passing NULL-terminated strings). Like this:
void matrix_sum(int **matrix, int size)
BUT for this case you can't call the function with a "normal" array. You need to use a pointer to a pointer or a pointer to an array.
int **matrix;
// make sure to allocate enough memory for this before initializing.
or:
int *matrix[];
For returning an array you can just return a pointer to a pointer like you did in your code example.
But you don't need to return an array, because if you change a value in an array, (in a different function) the value will stay changed in every other function.
A short example for this:
#include <stdio.h>
void put_zeros(int matrix[][3])
{
int i;
int j;
i = 0;
while (i < 3)
{
j = 0;
while (j < 3)
{
matrix[i][j] = 0;
j++;
}
i++;
}
}
void print_matrix(int matrix[][3])
{
int i;
int j;
i = 0;
while (i < 3)
{
j = 0;
while (j < 3)
{
printf("%d ", matrix[i][j]);
j++;
}
printf("\n");
i++;
}
}
int main(void)
{
int matrix_first[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
print_matrix(matrix_first);
put_zeros(matrix_first);
print_matrix(matrix_first);
}
This will print "1 2 3 4 5 6 7 8 9" because that's the first value we assigned.
After calling put_zeros it will contain and print "0 0 0 0 0 0 0 0 0" without the put_zeros returning the array.
1 2 3
4 5 6
7 8 9
0 0 0
0 0 0
0 0 0
i am having error while running this code
negativenoinmatrix.c:10:16: error: subscripted value is neither array nor pointer nor vector
if(z[i][j]<0)
i want to calculate the number of negative integers in a matrix
#include <stdio.h>
int negnumbers(int *z, int n, int m)
{
int count = 0;
int i = 0;
int j = m - 1;
while (j >= 0 && i < n)
{
if (z[i][j] < 0)
{
count += (j + 1);
i += 1;
}
else
j -= -1;
}
return count;
}
int main()
{
int n = 3, m = 4;
int a[n][m];
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
scanf("%d", &a[i][j]);
}
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
printf("%d ", a[i][j]);
printf("\n");
}
int val = negnumbers((int *) a, 3, 4);
printf("%d", val);
}
The function needs to accept a pointer to an array, not a pointer to a single item. Change it to
int negnumbers(int n, int m, int z[n][m])
...
int val = negnumbers(3, 4, a);
(Where int z[n][m], as per the rule of "array adjustment", will get changed by the compiler internally to a pointer to the first element, int (*z)[m].)
When you pass a 2-d array to a function, at least the 2nd dimension must be specified. Change to this:
int negnumbers(int z[][4],int n,int m)
You can then use this more straightforward approach to counting the negative numbers:
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (z[i][j] < 0)
count++;
}
}
You are calling a pointer z, and also creating a dynamic matrix out of it. So you need to allocate some memory for it which can be done with:
malloc(z[i][j])
Then after you're done, make sure you deallocate the memory now or else you'll have a memory leak, which you can read more about at Memory Leaks wikipedia.
This is done by calling free(...)
Hope this solves the not an array or pointer error!
int main()
{
double *array;
long int n;
n=10000000;//10^7
array = (double *) malloc(n*sizeof(double));
return 0;
}
basically, I want to use this code for a really big aray into a 2 dimensional array, which will have dimensions [very large][4].
If you want a 2D array, then allocate a 2D array. It's that simple.
double (*pArr)[4] = malloc(10000000 * sizeof pArr[0]);
Notes:
do not cast the return value of malloc().
use sizeof pArr[0] instead of sizeof(TheDataType) for defensive programming reasons.
This seems working on Wandbox.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
double (* array)[4];
long int n;
int i, j;
n=10000000;//10^7
array = (double (*)[4]) malloc(n*sizeof(double[4]));
printf("%u\n",(unsigned int)sizeof(array[0]));
printf("%u\n",(unsigned int)sizeof(double[4]));
for (i = 0; i <n; i++) {
for (j = 0; j < 4; j++) array[i][j] = (double)i * j;
}
for (i = 0; i < 10; i++) {
for (j = 0; j < 4; j++) printf("%f ", array[i][j]);
putchar('\n');
}
for (i = n - 10; i < n; i++) {
for (j = 0; j < 4; j++) printf("%f ", array[i][j]);
putchar('\n');
}
free(array);
return 0;
}
int n = 100000;
double** array = malloc(sizeof(double*)*n);
for (int i = 0; i < n; ++i)
{
array[i] = malloc(4*sizeof(double));
}
Also note that we don't cast the malloc's result(Do I cast the result of malloc?).