1)
How to access array element with array of pointers?
By pointer to an array we can access like this (∗a)[0]
,(∗a)[22]
,….. like this
right?
but how with array of pointer?
2)
Check these three codes , one of them use array and one of them use array of pointer, and 3rd one using double pointer, but all giving same output. Why??
#include <stdio.h>
int ptr[12];
int main(void) {
if(*(ptr+5)==*(ptr+3)){
printf("Equal");
}
else{
printf("Not Equal");
}
return 0;
}
#include <stdio.h>
int *ptr[12];
int main(void) {
if(*(ptr+5)==*(ptr+3)){
printf("Equal");
}
else{
printf("Not Equal");
}
return 0;
}
#include <stdio.h>
int **ptr[12];
int main(void) {
if(*(ptr+5)==*(ptr+3)){
printf("Equal");
}
else{
printf("Not Equal");
}
return 0;
}
In *(ptr+5):
ptr is the name of an array.
When an array is used in an expression and is not the operand of sizeof or unary & and is not a string literal used to initialize an array, it is converted to a pointer to its first element. So ptr points to element 0 of the array.
ptr+5 adds five, resulting in a pointer to element 5 of the array.
* dereferences the pointer, producing the contents of element 5 of the array.
Since the array is defined outside any function, it is initialized to zero. Therefore element 5 is zero, so *(ptr+5) is zero. Similarly, *(ptr+3) is zero, so comparing them shows they are equal.
The examples with int ptr[12];, int *ptr[12];, and int **ptr[12]; just change the types of the elements in the array. In each case *(ptr+5) and *(ptr+3) refer to elements 5 and 3 of the array. In each case, the values of the elements are zero (null pointers for the pointer types).
If you want to see differences between different elements of the array, then assign different values to the elements of the array.
Just keep incrementing the pointer as you go along reading the array. Analyze the
code below:
#include <stdio.h>
int main(void) {
int *ptr[3];
int a[] = { 0,1,2};
int b[] = { 3,4,5 };
int c[] = { 6,7,8 };
ptr[0] = a;
ptr[1] = b;
ptr[2] = c;
for (int i = 0;i < 3;i++)
printf("%d %d %d\n",*ptr[0]++,*ptr[1]++,*ptr[2]++);
return 0;
}
Answered in comments.
Related
Can we directly insert a 1D array to a 2D array?
For example I have this code:
void insert(int[]data , int**collection)
{
collection[1] = data
}
int main()
{
int data[2]= {1,3}
int collection[2][2];
insert(data,&collection);
}
Will this work?
You cannot insert a 1D array to 2D array the way you are doing. Use memcpy to copy the elements of 1D array to 2D array, like this:
memcpy(collection[1], data, 2 * sizeof(int));
this will copy the 2 integer elements of data array to collection[1].
Besides, a couple of problems in your code. Lets discuss them:
First:
insert(data,&collection);
^
You don't need to pass the address of collection. Note that, an array, when used in an expression, will convert to pointer to its first element (there are few exceptions to this rule). That means, when you pass collection, it will convert to type int (*)[2]. Just do:
insert(data, collection);
Second:
void insert(int[]data , int**collection)
int[]data is wrong. The first parameter of insert() should be int data[2] or int data[], both are equivalent to int * data. You can use either of them.
The second argument to insert() is collection array which is a 2D array of integers. When you pass it to insert(), it will decay to pointer whose type is int (*)[2]. The type of second parameter of insert() is int ** which is not compatible with the argument that you are passing to insert() function. The second parameter of insert() function should be int collection[2][2] or int collection[][2], both are equivalent to int (*collection)[2].
Putting these altogether, you can do:
#include <stdio.h>
#include <string.h>
#define ROW 2
#define COL 2
void insert(int data[ROW], int collection[ROW][COL]) {
//for demonstration purpose, copying elements of data array
//to all elements (1D array) of collection array.
for (int i = 0; i < ROW; ++i) {
memcpy(collection[i], data, COL * sizeof(int));
}
}
int main(void) {
int data[COL] = {1, 3};
int collection[ROW][COL];
insert(data, collection);
for (int i = 0; i < 2; ++i) {
for (int j = 0; j < 2; ++j) {
printf("collection[%d][%d] : %d ", i, j, collection[i][j]);
}
printf("\n");
}
return 0;
}
Output:
# ./a.out
collection[0][0] : 1 collection[0][1] : 3
collection[1][0] : 1 collection[1][1] : 3
I need to get a pointer to a 2D array. The sizes ARE known at compile time if that helps. I need to perform an action a certain array based on the incoming value of a variable.
//Global arrays
// int c[6000][1000];
// int a[6000][1000];
void fun(int x){
//Setup a pointer here
//Possible solution: int (*pointer)[6000][1000];
int **pointer;
if (x == 0){
pointer = c;
}
else{
pointer = a;
}
//Modify pointer here and have changes reflect back to the array it was based off of
pointer[0][17] = 42;
}
I have looked at close to a dozen different stack overflow articles on how to do this but I cannot find a way to just a get a simple pointer to a 2D array.
//Global arrays
int c[6000][1000];
int a[6000][1000];
void fun(int x) {
int (* ptr)[1000];
if (x == 0) {
ptr = c;
} else {
ptr = a;
}
ptr[0][17] = 42;
}
Like this
//Global arrays
int c[6000][1000];
int a[6000][1000];
void fun(int x) {
if (x == 0) {
c[0][17] = 42;
} else {
a[0][17] = 42;
}
}
Accessing a 2D array using Pointers:
2D array is an array of 1D arrays which implies each row of a 2D array is a 1D array. So, think about two of your global arrays,
int c[6000][1000] and int a[6000][1000].
We can say c[0] is the address of row 0 of the first global 2D array. Similarly a[6000] is the address of row 6000 of the second global 2D array.
Now you want to find the c[0][17] and point that using a pointer which is basically, c[0][17] = *(c[0] + 17).
Also you can write for any other array elements, c[0] = *c and in general each element as, c[i][j] = *(c[i] + j) = ((c+i) + j).
So, if c is a 2D array of integer type then we can think that c is a pointer to a pointer to an integer which can be interpreted as int **c. Dereferencing *c gives you the address of row 0 or c[0] which is a pointer to an integer and again dereferencing c[0] gives you the first element of the 2D array, c[0][0] which is an integer.
You can test your code by accessing each element using pointer for a better understanding:
#include<stdio.h>
#include<stdlib.h>
//Global arrays
int c[6000][1000];
int a[6000][1000];
void fun(int x){
//Setup a pointer here
//Possible solution: int (*pointer)[6000][1000];
int (*pointer)[1000];
if (x == 0){
pointer = c;
}
else{
pointer = a;
}
//Modify pointer here and have changes reflect back to the array it was based off of
pointer[0][17] = 42;
}
int main(){
int num;
scanf("%d", &num);
fun(num);
if(num == 0){
printf("When num is %d, c[0][17] = %d\n", num, *(*(c) + 17));
}
else{
printf("When num is %d, a[0][17] = %d\n", num, *(a[0] + 17));
}
return 0;
}
int main()
{
unsigned char a[3];
unsigned char (*p)[3]=NULL;
unsigned char *q=NULL;
int i = 0;
a[0]=0;
a[1]=1;
a[2]=2;
p=&a;
for(i=0;i<3;i++){
if((*p)[3] == a[3]){
printf("*p[%d]:%d a[%d]:%d",i,(*p)[3],i,a[3]);
}
}
}
o/p:
*p[0]:0 a[0]:0*p[1]:0 a[1]:0*p[2]:0 a[2]:0
Exited: ExitFailure 14
I want to copy an array of size 3 to a pointer and to do a comparision. I have written a sample program. But i'm getting an error value.
I ran this using an online c compiler . (codepad.org)
Please help me in identifying my mistakes.
Your variable p is an array, not a pointer. You can't re-assign an array to point somewhere else, so the line
p = &a;
is not valid.
Also, C indexes from 0 as you seem to know, so comparisons using index [3] for arrays of size 3 are not valid.
Further, in your comparison loop you're not actually using i to index, but instead always comparing using the invalid constant index [3].
It's not very clear from your code (q is not used, for instance), but it sounds as if you want to do something like:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
unsigned char a[3];
unsigned char *p;
p = malloc(sizeof a);
if(p != NULL) /* If allocation succeeded, p is valid. */
{
int i;
memcpy(p, a, sizeof a);
for(i = 0; i < sizeof a; ++i)
{
if(p[i] == a[i])
printf("p[%d]:%d a[%d]:%d\n", i, p[i], i, a[i]);
}
free(p);
}
Of course, this will always print all the numbers, since memcpy() will never fail to copy the memory. :)
Here You have declared the return type of main function as int, but you are not returning anything from it.
So return any integer value (like 1) or make the main function's return type void.
I have the following function in C:
int[] function(int a){
int * var = (int*)malloc(sizeof(int)*tags);
....
}
*var is it a pointer to an array var?
If yes, how can I return the array (var) in the function?
You can't really return an array from a function, but a pointer:
int * function(int a){
int * var = malloc(sizeof(int)*tags);
//....
return var;
}
This code below could clarify a bit how array and pointers works.
The function will allocate memory for "tags" int variables, then it will initialize each element with a number and return the memory segment that points to the array.
From the main function we will cycle and print the array element, then we will free the no longer needed memory.
#include <stdio.h>
#include <stdlib.h>
int *function(unsigned int tags) {
int i;
int *var = malloc(sizeof(int)*tags);
for (i=0; i < tags; i++) {
var[i] = i;
}
return var;
}
int main() {
int *x;
int i;
x = function(10);
for (i=0; i < 10; i++) {
printf("TEST: %i\n", x[i]);
}
free(x); x=NULL;
return 0;
}
How about:
int* function(int tags){
int * var = malloc(sizeof(int)*tags);
//....
return var;
}
Arrays and pointers to the base element type are (mostly) synonymous in C/C++, so you can return a pointer to the first element of an array and use that as if it was the array itself.
Note, your code has an input parameter a, but using tags to allocate the memory for the array. I assumed in the above code that you wanted to use the input parameter for that purpose
Also, you will have to call free() on the pointer returned by function above, when you are no longer using the array, to avoid memory leaks. malloc above allocates memory enough to hold tags number of ints, so the array is equivalent to int var[tags];
UPDATE: removed cast for malloc's return
In C, functions cannot return array types. For your purposes, you want to return a pointer to int:
int *function(int a)
{
int *var = malloc(sizeof *var * tags); // where is tags defined?
// are you sure you don't mean a here?
...
return var;
}
This will allocate a block of memory large enough to hold tags integer values and assign the address of the first element of that block to var. Note that var is a pointer to int, not a pointer to an array of int. That pointer is what gets returned from the function.
You can use the subscript oprerator on a pointer expression as though it were an array, like so:
int a = ...;
int *arr = function(a);
...
arr[0] = 0;
arr[1] = 1;
...
arr is a pointer expression, not an array expression, so sizeof arr will return the size of the pointer type, not the size of the block of memory that it points to (because of this, you will want to keep track of the number of elements you allocated separately).
In C an array is basically the same type as a pointer to an element of the array.
So char[] is basically char*
Don't forget to keep track of the size of the array, also I noticed that tags seems to be a global variable, most of the time it's a good idea to avoid global variables
Here is some example code:
#include <stdio.h>
#include <stdlib.h>
int* foo(size_t arrSize){
int* arr = (int*) malloc(sizeof(int)*arrSize);
return arr;
}
int main (int argc, char** argv){
printf("Printing array:\n");
int* arr = foo(42);
for(int i=0; i <42; i++){
arr[i]=i;
}
for (int i=0; i < 42; i++){
printf("Element: %d: %d\n", i, arr[i]);
}
free(arr);
return 0;
}
If this is possible:
#include <stdio.h>
#include <process.h>
#define SIZE 5
void PassingArray(int arr[])
{
int i=0;
for(i=0 ; i<SIZE ; i++)
{
printf("%d, ", arr[i]);
}
printf("\n");
}
main()
{
int myIntArray[5] = {1, 2, 3, 4, 5};
PassingArray(myIntArray);
system("PAUSE");
}
Then why the following is illegal?
#include <stdio.h>
#include <process.h>
#define SIZE 5
int ReturningArray()[]
{
int myIntArray[5] = {1, 2, 3, 4, 5};
return myIntArray;
}
main()
{
int myArray[] = ReturningArray();
system("PAUSE");
}
You're not returning an int, but you're returning the array. This is the same value as &myIntArray[0]. int ReturningArray()[] is not a valid function prototype.
There's multiple reasons why this doesn't work.
The first is simply that it's prohibited by the language - the return type of a function shall not be an array (it also can't be a function).
The second is that even if you were allowed to declare ReturningArray as you do, you could never write a valid return statement in that function - an expression with array type that is not the subject of the unary & or sizeof operators evaluates to a pointer to the first element of the array, which no longer has array type. So you can't actually make return see an array.
Thirdly, even if we somehow had a function returning an array type, you couldn't use that return value as the initialiser of an array variable - the return value would again evaluate to a pointer to the first element of the array: in this case a pointer to int, and a pointer to int isn't a suitable initialiser for an array of int.
There are several problems with this code.
You are placing the brackets at the wrong place. Instead of
int ReturningArray()[]
it should be
int* ReturningArray()
You are returning a local variable. Local variables only exist during the execution of the function and will be removed afterwards.
In order to make this work you will have to malloc the int array and return the pointer to the array:
#include <stdio.h>
#include <malloc.h>
#define SIZE 5
int* ReturningArray()
{
int *myIntArray = (int *)malloc(SIZE * sizeof(int));
myIntArray[0] = 1;
myIntArray[1] = 2;
myIntArray[2] = 3;
myIntArray[3] = 4;
myIntArray[4] = 5;
return myIntArray;
}
int main(void)
{
int i;
int* myArray = ReturningArray();
for(i=0;i<SIZE;i++) {
printf("%d\n", myArray[i]);
}
free(myArray); // free the memory again
system("PAUSE");
return 0;
}
PassingArray is legal, but it does not pass an array. It passes a pointer to the first element of an array. void PassingArray(int arr[]) is a confusing synonym for void PassingArray(int *arr). You can't pass an array by value in C.
ReturningArray is not allowed, you can't return an array by value in C either. The usual workaround is to return a struct containing an array:
typedef struct ReturnArray {
int contents[5];
} ReturnArray;
ReturnArray ReturningArray()
{
ReturnArray x = {{1, 2, 3, 4, 5}};
return x;
}
Arrays are second-class citizens in C, the fact that they can't be passed or returned by value is historically related to the fact that they can't be copied by assignment. And as far as I know, the reason for that is buried in the early development of C, long before it was standardized, when it wasn't quite decided how arrays were going to work.
You can't return array from a function, but It is possible that you can declare a function returning a (reference in C++) or pointer to array as follows:
int myIntArray[] = {1, 2, 3, 4, 5};
int (*ReturningArray())[sizeof(myIntArray)/sizeof(int)] {
return &myIntArray;
}