I know how can I use pointers in C with the 1-D array. like the following:
but what if we have 2-D arrays? how can I address them by pointers?
Thank you.
#include <stdio.h>
int main() {
int dar[4] = {1,2,3,4};
int *sar = NULL;
sar = dar;
for (int i = 0; i < 4; i++) {
printf("%d ", *(sar + i));
}
}
This may also help.
#include <stdio.h>
int main()
{
int dar[2][3] = {1,2,3,
4,5,6};
int index=0;
for (int line = 0; line < 2; line++)
{
for (int col=0; col<3;col++)
{
printf("%d ", *(dar[0]+index));
index=index+1;
}
printf("\n");
}
return (0);
}
Thanks to #Qubit
I solved the problem. I post the answer for future reference.
#include <stdio.h>
int main() {
int dar[2][3] = {{1,2,3},
{4,5,6}};
int *sar = NULL;
int *bar = NULL;
sar = dar[0];
bar = dar[1];
for (int i = 0; i < 3; i++) {
printf("%d ", *(sar+i));
}
printf("\n");
for (int j = 0; j < 3; j++) {
printf("%d ",*(bar+j));
}
printf("\n");
}
A 2-D array is... a 1-D array of 1-D arrays, and you can use the common pointer arithmetics on both.
That means that you can simply do:
#include <stdio.h>
int main() {
int dar[2][3] = {{1,2,3},
{4,5,6}};
for (int i = 0; i < 2; i++) {
int *bar = *(dar + i); // pointer to the row
for (int j = 0; j < 3; j++) {
printf("%d ",*(bar+j)); // access the values
}
printf("\n");
}
printf("\n");
}
It works, because in dar + i, dar decays to a pointer to its first row, so *(dar + 1) (which is *by definition dar[i]) represents the i-th row and in turn decays to a pointer to the first element of that row.
Disclaimer: this is just an addition to JJcopl's answer, but too rich to fit in a comment...
Related
This code is not giving any syntax error but is has some logical error and it seems the program is working before swap function and the values are not swapping while running the program the output window freezes. Please help:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void swap(char *a, char *b); //function to swap strings
int main() {
char *fruits[] = { "lemon", "grapes", "water melon" };
char minstr[15];
int min_ind;
int c;
for (int i = 0; i < 3; i++) {
strcpy(minstr, fruits[i]); //copies the ith value into minstr array from fruits array
printf("%s\n", minstr);
min_ind = i;
for (int j = i + 1; j < 3; j++) {
c = (strcmp(fruits[j], minstr));
printf("value of c is %d\n", c);
if (c < 0)
min_ind = j;
printf("value of min ind %d\n",min_ind);
}
if (min_ind != i)
swap(minstr, *(fruits + i));
}
printf("the sorted aray is:\n");
for (int k = 0; k < 3; k++) {
printf("%s\n", fruits[k]);
}
return 0;
}
void swap(char *a, char *b) {
char *temp = (char *)malloc((strlen(a) + 1) * sizeof(char));
strcpy(temp, a);
` strcpy(a, b);
strcpy(b, temp);
free(temp);
}
Your code does not swap the string pointers, it attempts to swap thestring contents. This assumes both strings point to char that are large enough to accommodate the new strings and that are modifiable. This is not the case of the string literals you intialize fruits with.
You should just swap the pointers:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
const char *fruits[] = { "lemon", "grapes", "water melon" };
for (int i = 0; i < 3; i++) {
int min_ind = i;
for (int j = i + 1; j < 3; j++) {
int c = strcmp(fruits[j], fruits[i]);
printf("value of c is %d\n", c);
if (c < 0)
min_ind = j;
printf("value of min ind %d\n", min_ind);
}
if (min_ind != i) {
const char *temp = fruits[i];
fruits[i] = fruits[j];
fruits[j] = temp;
}
}
printf("the sorted array is:\n");
for (int k = 0; k < 3; k++) {
printf("%s\n", fruits[k]);
}
return 0;
}
So I read dozens of examples of passing an 2D array pointer to function to get/change values of that array in function. But is it possible to create (allocate memory) inside the function. Something like this:
#include <stdio.h>
void createArr(int** arrPtr, int x, int y);
int main() {
int x, y; //Dimension
int i, j; //Loop indexes
int** arr; //2D array pointer
arr = NULL;
x=3;
y=4;
createArr(arr, x, y);
for (i = 0; i < x; ++i) {
for (j = 0; j < y; ++j) {
printf("%d\n", arr[i][j]);
}
printf("\n");
}
_getch();
}
void createArr(int** arrPtr, int x, int y) {
int i, j; //Loop indexes
arrPtr = malloc(x*sizeof(int*));
for (i = 0; i < x; ++i)
arrPtr[i] = malloc(y*sizeof(int));
for (i = 0; i < x; ++i) {
for (j = 0; j < y; ++j) {
arrPtr[i][j] = i + j;
}
}
}
Forget about pointer-to-pointers. They have nothing to do with 2D arrays.
How to do it correctly: How do I correctly set up, access, and free a multidimensional array in C?.
One of many reasons why it is wrong to use pointer-to-pointer: Why do I need to use type** to point to type*?.
Example of how you could do it properly:
#include <stdio.h>
#include <stdlib.h>
void* create_2D_array (size_t x, size_t y)
{
int (*array)[y] = malloc( sizeof(int[x][y]) );
for (size_t i = 0; i < x; ++i)
{
for (size_t j = 0; j < y; ++j)
{
array[i][j] = (int)(i + j);
}
}
return array;
}
void print_2D_array (size_t x, size_t y, int array[x][y])
{
for (size_t i = 0; i < x; ++i)
{
for (size_t j = 0; j < y; ++j)
{
printf("%d ", array[i][j]);
}
printf("\n");
}
}
int main (void)
{
size_t x = 5;
size_t y = 3;
int (*arr_2D)[y];
arr_2D = create_2D_array(x, y);
print_2D_array(x, y, arr_2D);
free(arr_2D);
return 0;
}
Yes, passing a pointer to int ** (but 3 stars is considered bad style), I suggest to return an allocated variable from your function:
int **createArr(int x, int y)
{
int **arrPtr;
int i, j; //Loop indexes
arrPtr = malloc(x*sizeof(int*));
if (arrPtr == NULL) { /* always check the return of malloc */
perror("malloc");
exit(EXIT_FAILURE);
}
for (i = 0; i < x; ++i) {
arrPtr[i] = malloc(y*sizeof(int));
if (arrPtr[i] == NULL) {
perror("malloc");
exit(EXIT_FAILURE);
}
}
for (i = 0; i < x; ++i) {
for (j = 0; j < y; ++j) {
arrPtr[i][j] = i + j;
}
}
return arrPtr;
}
Call it using:
arr = createArr(x, y);
Yes, an array can be initialized this way. As long as you pass a pointer, the memory address should remain the same. So, if you assign anything to the pointer it will valid.
Think of an a[] as a* pointer to the first element
a [][] will be a** pointer to a pointer of the first element or a pointer to the first array (first row of a table)
I am trying to create a structure that will have two integer values, an array, and two 2-D matrices using my code below. I can initialize the structure with the integers and array just fine, and my 'Gen' function will create the random values I want for the array.
However, when I try adding in the matrix components, I run into a problem. My compiler gives me a warning: "initialization from incompatible pointer type". If I understand what I have read so far, this is because the structure needs to be pointed to an array of pointers that represent each row in the matrix. I don't know the syntax for that.
A quick note: the other topics I've seen that are related to this issue all initialize the structure in a function other than the main() function, so I haven't found those solutions helpful.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include <string.h>
// Define structure
typedef struct {
int row;
int col;
int *arr;
int **mat1;
int **mat2;
}container;
// Function headers
void Gen(container Thing);
int main() {
int row = 5;
int col = 6;
int A[row];
int M1[row][col];
int M2[row][col+1];
// Initialize structure
container Object = {row, col, A, M1, M2};
// Run "Gen" function
Gen(Object);
int i, j; // Index variables
// Display the array
for(i = 0; i < row; i++)
{
printf("%i ", Object.arr[i]);
}
printf("\n\n");
// Display the numbers from the matrices
for(j = 0; j < Object.row; j++)
{
for(i = 0; i < Object.col; i++)
{
printf("%i ", Object.mat1[j][i]);
}
printf("\n");
}
printf("\n");
for(j = 0; j < Object.row; j++)
{
for(i = 0; i < Object.col; i++)
{
printf("%i ", Object.mat2[j][i]);
}
printf("\n");
}
return (EXIT_SUCCESS);
}
// Function to generate random values in the array & matrices
void Gen(container Thing)
{
int i, j;
srand(time(NULL));
// Generate random values for the array
for(i = 0; i < Thing.row; i++)
{
Thing.arr[i] = rand() % 5;
}
// Generate random values for the matrix
for(j = 0; j < Thing.row; j++)
{
for(i = 0; i < Thing.col; i++)
{
Thing.mat1[j][i] = rand() % 5;
Thing.mat2[j][i] = rand() % 5;
}
}
} // End of "Gen" function
container Object = {row, col, A, M1, M2};
is wrong since the type of M1 is int[row][col], which can decay to int (*)[col] but not to int**. You have the same problem with M2.
You'll need to rethink your strategy for generating a container.
For example:
int main() {
int row = 5;
int col = 6;
int A[row];
int* M1[row];
int* M2[row];
for ( int i = 0; i < row; ++i )
{
M1[i] = malloc(sizeof(M1[i][0])*col);
M2[i] = malloc(sizeof(M1[i][0])*(col+1));
}
// Initialize structure
container Object = {row, col, A, M1, M2};
...
for ( int i = 0; i < row; ++i )
{
free(M1[i]);
free(M2[i]);
}
return (EXIT_SUCCESS);
}
I am trying to print a 2D array by passing it to a function, but I got weird results. Here is my code.
#include <stdio.h>
int main()
{
int b[2][3] = {{1,2,3},{4,5,6}};
printArray(b);
return 0;
}
void printArray(int (*ptr)[3])
{
int i, j;
for(i = 0; i < 2; i++)
{
for(j = 0; j < 3; j++)
{
printf("%d\t", *((*ptr+i)+j));
}
printf("\n");
}
}
However, the output is
1 2 3
2 3 4
I think it is something to do with my 'j' variable but I can't seem to pinpoint it. Please help.
You need to apply the addition operator before using the dereference operator. You need to use parenthesis as the dereference operator(*) has higher precedence than the addition operator(+).
So, this
printf("%d\t", *((*ptr+i)+j));
should be
printf("%d\t", *((*(ptr+i))+j));
or better
printf("%d\t", ptr[i][j]);
Also, you need to move the function printArray before main or provide a function prototype before main like:
void printArray(int (*ptr)[3]);
You need to multiply i by 3 before adding j ...
printf("%d\t", *((*ptr+(i*3))+j));
Abandoning indexes in favor of pointers, assuming matrix is stored by rows (whic is normally the case):
#include <stdio.h>
void printArray(int *);
int main()
{
int b[2][3] = {{1,2,3},{4,5,6}};
printArray((int*)b);
return 0;
}
void printArray(int *ptr)
{
int i, j;
for(i = 0; i < 2; i++)
{
for(j = 0; j < 3; j++)
{
printf("%d\t", *ptr++);
}
printf("\n");
}
}
Outputs:
1 2 3
4 5 6
printArray can take nb_column nb_line param and deal with all sort of 2D array
#include <stdio.h>
static void printArray(int *ptr, int nb_columns, int nb_lines)
{
int i, j;
for(i = 0; i < nb_lines; i++)
{
for(j = 0; j < nb_columns; j++)
{
printf("%d\t", *(ptr++));
}
printf("\n");
}
}
int main()
{
int b[2][3] = {{1,2,3},{4,5,6}};
printArray((int *)b, 3, 2);
return 0;
}
I wrote this simple piece of code to dynamically allocate a 4-dimensional array:
#include <stdlib.h>
#include <stdio.h>
int**** alloc() {
int i,j,k;
int ****matrix;
int x,y,z,n_pairs;
x= 62;
y= 45;
z= 28;
n_pairs = 4;
matrix = (int ****) malloc(x*sizeof(int***));
for (i=0; i<x; i++) {
matrix[i] = (int ***) malloc(y*sizeof(int**));
if(matrix[i]==NULL)
return NULL;
for (j=0; j<y; j++) {
matrix[i][j] = (int **) malloc(z*sizeof(int*));
if (matrix[i][j] == NULL)
return NULL;
for (k=0; k<n_pairs; k++) {
matrix[i][j][k] = (int *)calloc(n_pairs,sizeof(int));
if (matrix[i][j][k] == NULL)
return NULL;
}
}
}
return matrix;
}
void freeMatrix(int ****m) {
int i,j,k;
int x,y,z;
x= 62;
y= 45;
z= 28;
for(i=0; i<x; i++) {
for(j=0; j<y; j++) {
for(k=0; k<z; k++)
free(m[i][j][k]);
free(m[i][j]);
}
free(m[i]);
}
free(m);
}
int main() {
int i,j,k,h;
int ****m = NULL;
m = alloc();
for(i=0;i<62;i++)
for(j=0;j<45;j++)
for(k=0;k<28;k++)
for(h=0;h<4;h++)
printf("%d\t",m[i][j][k][h]);
system("pause");
return 0;
}
the problem is that I this code results in an Access Violation when I try to execute it.
Isn't it the correct way to allocate/free a multidimensional array? If yes, then what is the problem?
One problem is here:
for (k=0; k<n_pairs; k++) { //<----- This should read `k<z'
matrix[i][j][k] = (int *)calloc(n_pairs,sizeof(int));
You probably meant to loop to z, not to n_pairs.
if u make a matrix the correct way is to allocate all the memory u need, then dived it up.
for 2.dim
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
int i;
int ** matrix;
int rows = 10;
int colums =10;
matrix = (int**)malloc(rows*sizeof(int*));
matrix[0] = (int*)malloc(rows*colums*sizeof(int));
for(i =1; i<rows;i++)
matrix[i] = &matrix[i-1][colums];
free(matrix[0]);
free(matrix);
return 0;
}
this is for having a continues memory area for the matrix. this can be faster