12.4: Arrays, Pointers and Such
- Page ID
- 29107
\( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)
\( \newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\)
( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\)
\( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)
\( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\)
\( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)
\( \newcommand{\Span}{\mathrm{span}}\)
\( \newcommand{\id}{\mathrm{id}}\)
\( \newcommand{\Span}{\mathrm{span}}\)
\( \newcommand{\kernel}{\mathrm{null}\,}\)
\( \newcommand{\range}{\mathrm{range}\,}\)
\( \newcommand{\RealPart}{\mathrm{Re}}\)
\( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)
\( \newcommand{\Argument}{\mathrm{Arg}}\)
\( \newcommand{\norm}[1]{\| #1 \|}\)
\( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)
\( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\AA}{\unicode[.8,0]{x212B}}\)
\( \newcommand{\vectorA}[1]{\vec{#1}} % arrow\)
\( \newcommand{\vectorAt}[1]{\vec{\text{#1}}} % arrow\)
\( \newcommand{\vectorB}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vectorC}[1]{\textbf{#1}} \)
\( \newcommand{\vectorD}[1]{\overrightarrow{#1}} \)
\( \newcommand{\vectorDt}[1]{\overrightarrow{\text{#1}}} \)
\( \newcommand{\vectE}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash{\mathbf {#1}}}} \)
\( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)
\(\newcommand{\avec}{\mathbf a}\) \(\newcommand{\bvec}{\mathbf b}\) \(\newcommand{\cvec}{\mathbf c}\) \(\newcommand{\dvec}{\mathbf d}\) \(\newcommand{\dtil}{\widetilde{\mathbf d}}\) \(\newcommand{\evec}{\mathbf e}\) \(\newcommand{\fvec}{\mathbf f}\) \(\newcommand{\nvec}{\mathbf n}\) \(\newcommand{\pvec}{\mathbf p}\) \(\newcommand{\qvec}{\mathbf q}\) \(\newcommand{\svec}{\mathbf s}\) \(\newcommand{\tvec}{\mathbf t}\) \(\newcommand{\uvec}{\mathbf u}\) \(\newcommand{\vvec}{\mathbf v}\) \(\newcommand{\wvec}{\mathbf w}\) \(\newcommand{\xvec}{\mathbf x}\) \(\newcommand{\yvec}{\mathbf y}\) \(\newcommand{\zvec}{\mathbf z}\) \(\newcommand{\rvec}{\mathbf r}\) \(\newcommand{\mvec}{\mathbf m}\) \(\newcommand{\zerovec}{\mathbf 0}\) \(\newcommand{\onevec}{\mathbf 1}\) \(\newcommand{\real}{\mathbb R}\) \(\newcommand{\twovec}[2]{\left[\begin{array}{r}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\ctwovec}[2]{\left[\begin{array}{c}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\threevec}[3]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\cthreevec}[3]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\fourvec}[4]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\cfourvec}[4]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\fivevec}[5]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\cfivevec}[5]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\mattwo}[4]{\left[\begin{array}{rr}#1 \amp #2 \\ #3 \amp #4 \\ \end{array}\right]}\) \(\newcommand{\laspan}[1]{\text{Span}\{#1\}}\) \(\newcommand{\bcal}{\cal B}\) \(\newcommand{\ccal}{\cal C}\) \(\newcommand{\scal}{\cal S}\) \(\newcommand{\wcal}{\cal W}\) \(\newcommand{\ecal}{\cal E}\) \(\newcommand{\coords}[2]{\left\{#1\right\}_{#2}}\) \(\newcommand{\gray}[1]{\color{gray}{#1}}\) \(\newcommand{\lgray}[1]{\color{lightgray}{#1}}\) \(\newcommand{\rank}{\operatorname{rank}}\) \(\newcommand{\row}{\text{Row}}\) \(\newcommand{\col}{\text{Col}}\) \(\renewcommand{\row}{\text{Row}}\) \(\newcommand{\nul}{\text{Nul}}\) \(\newcommand{\var}{\text{Var}}\) \(\newcommand{\corr}{\text{corr}}\) \(\newcommand{\len}[1]{\left|#1\right|}\) \(\newcommand{\bbar}{\overline{\bvec}}\) \(\newcommand{\bhat}{\widehat{\bvec}}\) \(\newcommand{\bperp}{\bvec^\perp}\) \(\newcommand{\xhat}{\widehat{\xvec}}\) \(\newcommand{\vhat}{\widehat{\vvec}}\) \(\newcommand{\uhat}{\widehat{\uvec}}\) \(\newcommand{\what}{\widehat{\wvec}}\) \(\newcommand{\Sighat}{\widehat{\Sigma}}\) \(\newcommand{\lt}{<}\) \(\newcommand{\gt}{>}\) \(\newcommand{\amp}{&}\) \(\definecolor{fillinmathshade}{gray}{0.9}\)Difference between pointer and array in C++?
Pointers are used for storing address of dynamically allocated arrays and for arrays which are passed as arguments to functions. In other contexts, arrays and pointer are two different things, see the following programs to justify this statement.
The behavior of the sizeof operator is shown below
/ 1st program to show that array and pointers are different #includeusing namespace std; int main() { int arr[] = {10, 20, 30, 40, 50, 60}; int *ptr = arr; // sizof(int) * (number of element in arr[]) is printed cout << "Size of arr[] "<< sizeof(arr)<<"\n"; // sizeof a pointer is printed which is same for all type // of pointers (char *, void *, etc) cout << "Size of ptr "<< sizeof(ptr); return 0; }
The array is 6 members * 4 bytes each, so we get 24 bytes for the variable arr. The pointer ptr, and all pointers, are 8 bytes, because they hold addresses, which are 8 bytes, or 64 bits.
Output:
Size of arr[] 24 Size of ptr 8
Assigning any address to an array variable is not allowed.
// Second program to show that array and pointers are different #include <iostream> using namespace std; int main() { int arr[] = {10, 20}, x = 10; int *ptr = &x; // This is fine because ptr is to hold addresses arr = &x; // Compiler Error this is an integer array, not meant to hold addresses return 0; }
Output:
Compiler Error: incompatible types when assigning to type 'int[2]' from type 'int *'
Although array and pointer are different things, following properties of array make them look similar.
- Array name gives address of first element of array.
Consider the following program for example.
// 1st program to show that array and pointers are different #include <iostream> using namespace std; int main() { int arr[] = {10, 100, 200, 40, 50, 60}; // Assigns address of array to ptr int *ptr = arr; cout << "Value of first element is " << *ptr; return 0; }
In the above code the value of arr is actually an address. From that address all of the members of the array are calculated - an int is 4 bytes, so the value of 10, as shown in the image (the image uses an array named v, instead of arr), is at specific address. The next value 100 is at that same address PLUS 4 - because integers are 4 bytes long. So, by saying arr[1] we are saying - the value we want, 100, is at the address of arr + 4 more bytes - because the value of 10 takes up the 4 bytes from the address 0x7fff9a9e7920 to 0x7fff9a9e7923
So really we are simply performing address arithmatic - it all depends on the type of the array, which determines how much memory each value takes up.
Output:
Value of first element is 10
- Array members are accessed using pointer arithmetic.
Compiler uses pointer arithmetic to access array element. For example, an expression like “arr[i]” is treated as *(arr + i) by the compiler. That is why the expressions like *(arr + i) work for array arr, and expressions like ptr[i] also work for pointer ptr.#include <iostream> using namespace std; int main() { int arr[] = {10, 20, 30, 40, 50, 60}; int *ptr = arr; cout << "arr[2] = "<< arr[2] <<"\n"; cout << "*(arr + 2) = "<< *(arr + 2)<<"\n"; cout << "ptr[2] = "<< ptr[2]<< "\n"; cout << "*(ptr + 2) = "<< *(ptr + 2)<< "\n"; return 0; }
-
Output:
arr[2] = 30 *(arr + 2) = 30 ptr[2] = 30 *(ptr + 2) = 30
- Array parameters are always passed as pointers, even when we use square brackets.filter_none
#include <iostream> using namespace std; int fun(int ptr[]) { int x = 10; // size of a pointer is printed cout << "sizeof(ptr) = " << sizeof(ptr) << endl; // This allowed because ptr is a pointer, not array ptr = &x; cout << "*ptr = " << *ptr << endl; return 0; } // Driver code int main() { int arr[] = {10, 20, 30, 40, 50, 60}; fun(arr); return 0; }
Output:
sizeof(ptr) = 8 *ptr = 10
Array Name as Pointers
An array name contains the address of first element of the array which acts like constant pointer. It means, the address stored in array name can’t be changed.
For example, if we have an array named val then val and &val[0] can be used interchangeably.
// C++ program to illustrate Array Name as Pointers in C++ #include <iostream> using namespace std; int main() { //Declare an array int newArr[3] = { 5, 10, 20 }; //declare pointer variable int *arrPtr; //Assign the address of newArr[0] to ptr // We could use arrPtr = &newArr[0];(both are same) arrPtr = newArr ; cout << "Elements of the array are: "; cout << arrPtr[0] << " " << arrPtr[1] << " " << arrPtr[2]; return 0; }
In looking at this code you may notice that when when we use the square brackets - [ ] - it is actually using the address. This is because the value stored in the newArr variable IS an address in memory.
Output: Elements of the array are: 5 10 20
Adapted from:
"Pointers in C/C++ with Examples" by Abhirav Kariya, Geeks for Geeks is licensed under CC BY-SA 4.0
"Pointers in C and C++ | Set 1 (Introduction, Arithmetic and Array)" by Abhirav Kariya, Geeks for Geeks is licensed under CC BY-SA 4.0
"Difference between pointer and array in C?" by Abhay Rathi, Geeks for Geeks is licensed under CC BY-SA 4.0