Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Pointer (computer programming)
(section)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
===C and C++=== In [[C (programming language)|C]] and [[C++]] pointers are variables that store addresses and can be ''null''. Each pointer has a type it points to, but one can freely cast between pointer types (but not between a function pointer and an object pointer). A special pointer type called the “void pointer” allows pointing to any (non-function) object, but is limited by the fact that it cannot be dereferenced directly (it shall be cast). The address itself can often be directly manipulated by casting a pointer to and from an integral type of sufficient size, though the results are implementation-defined and may indeed cause undefined behavior; while earlier C standards did not have an integral type that was guaranteed to be large enough, [[C99]] specifies the <code>uintptr_t</code> ''[[typedef]] name'' defined in <code>[[C_data_types#Fixed-width_integer_types|<stdint.h>]]</code>, but an implementation need not provide it. [[C++]] fully supports C pointers and C typecasting. It also supports a new group of typecasting operators to help catch some unintended dangerous casts at compile-time. Since [[C++11]], the [[C++ Standard Library|C++ standard library]] also provides [[smart pointer]]s (<code>unique_ptr</code>, <code>shared_ptr</code> and <code>weak_ptr</code>) which can be used in some situations as a safer alternative to primitive C pointers. C++ also supports another form of reference, quite different from a pointer, called simply a ''[[reference (C++)|reference]]'' or ''reference type''. '''Pointer arithmetic''', that is, the ability to modify a pointer's target address with arithmetic operations (as well as magnitude comparisons), is restricted by the language standard to remain within the bounds of a single array object (or just after it), and will otherwise invoke [[undefined behavior]]. Adding or subtracting from a pointer moves it by a multiple of the size of its [[datatype]]. For example, adding 1 to a pointer to 4-byte integer values will increment the pointer's pointed-to byte-address by 4. This has the effect of incrementing the pointer to point at the next element in a contiguous array of integers—which is often the intended result. Pointer arithmetic cannot be performed on <code>void</code> pointers because the [[void type]] has no size, and thus the pointed address can not be added to, although [[GNU Compiler Collection|gcc]] and other compilers will perform byte arithmetic on <code>void*</code> as a non-standard extension, treating it as if it were <code>char *</code>. Pointer arithmetic provides the programmer with a single way of dealing with different types: adding and subtracting the number of elements required instead of the actual offset in bytes. (Pointer arithmetic with <code>char *</code> pointers uses byte offsets, because <code>sizeof(char)</code> is 1 by definition.) In particular, the C definition explicitly declares that the syntax <code>a[n]</code>, which is the <code>n</code>-th element of the array <code>a</code>, is equivalent to <code>*(a + n)</code>, which is the content of the element pointed by <code>a + n</code>. This implies that <code>n[a]</code> is equivalent to <code>a[n]</code>, and one can write, e.g., <code>a[3]</code> or <code>3[a]</code> equally well to access the fourth element of an array <code>a</code>. While powerful, pointer arithmetic can be a source of [[Software bug|computer bugs]]. It tends to confuse novice [[programmer]]s, forcing them into different contexts: an expression can be an ordinary arithmetic one or a pointer arithmetic one, and sometimes it is easy to mistake one for the other. In response to this, many modern high-level computer languages (for example [[Java (programming language)|Java]]) do not permit direct access to memory using addresses. Also, the safe C dialect [[Cyclone programming language|Cyclone]] addresses many of the issues with pointers. See [[C (programming language)#Pointers|C programming language]] for more discussion. The '''<code>void</code> pointer''', or '''<code>void*</code>''', is supported in ANSI C and C++ as a generic pointer type. A pointer to <code>void</code> can store the address of any object (not function),{{efn|Some compilers allow storing the addresses of functions in void pointers. The C++ standard lists converting a function pointer to <code>void*</code> as a conditionally supported feature and the C standard says such conversions are "common extensions". This is required by the [[POSIX]] function <code>dlsym</code>.<ref>{{Cite web |title=CWG Issue 195 |url=https://cplusplus.github.io/CWG/issues/195.html |access-date=2024-02-15 |website=cplusplus.github.io}}</ref>}} and, in C, is implicitly converted to any other object pointer type on assignment, but it must be explicitly cast if dereferenced. [[The C Programming Language|K&R]] C used <code>char*</code> for the “type-agnostic pointer” purpose (before ANSI C). <syntaxhighlight lang="C"> int x = 4; void* p1 = &x; int* p2 = p1; // void* implicitly converted to int*: valid C, but not C++ int a = *p2; int b = *(int*)p1; // when dereferencing inline, there is no implicit conversion </syntaxhighlight> C++ does not allow the implicit conversion of <code>void*</code> to other pointer types, even in assignments. This was a design decision to avoid careless and even unintended casts, though most compilers only output warnings, not errors, when encountering other casts. <syntaxhighlight lang="Cpp"> int x = 4; void* p1 = &x; int* p2 = p1; // this fails in C++: there is no implicit conversion from void* int* p3 = (int*)p1; // C-style cast int* p4 = reinterpret_cast<int*>(p1); // C++ cast </syntaxhighlight> In C++, there is no <code>void&</code> (reference to void) to complement <code>void*</code> (pointer to void), because references behave like aliases to the variables they point to, and there can never be a variable whose type is <code>void</code>. ==== Pointer-to-member ==== <!-- →* redirects here. The correct redirect ->* cannot be made due to technical restrictions (WP:NCTR) --> In C++ pointers to non-static members of a class can be defined. If a class <code>C</code> has a member <code>T a</code> then <code>&C::a</code> is a pointer to the member <code>a</code> of type <code>T C::*</code>. This member can be an object or a [[Function pointer#Method pointers|function]].<ref>{{cite web|url=https://isocpp.org/wiki/faq/pointers-to-members|title=Pointers to Member Functions|access-date=2022-11-26|publisher=isocpp.org}}</ref> They can be used on the right-hand side of operators <code>.*</code> and <code>->*</code> to access the corresponding member. <syntaxhighlight lang="Cpp"> struct S { int a; int f() const {return a;} }; S s1{}; S* ptrS = &s1; int S::* ptr = &S::a; // pointer to S::a int (S::* fp)()const = &S::f; // pointer to S::f s1.*ptr = 1; std::cout << (s1.*fp)() << "\n"; // prints 1 ptrS->*ptr = 2; std::cout << (ptrS->*fp)() << "\n"; // prints 2 </syntaxhighlight> ====Pointer declaration syntax overview==== These pointer declarations cover most variants of pointer declarations. Of course it is possible to have triple pointers, but the main principles behind a triple pointer already exist in a double pointer. The naming used here is what the expression <code>typeid(type).name()</code> equals for each of these types when using [[g++]] or [[clang]].<ref>{{cite web|url=https://linux.die.net/man/1/c++filt|title=c++filt(1) - Linux man page}}</ref><ref>{{cite web|url=http://refspecs.linux-foundation.org/cxxabi-1.83.html#mangling|title=Itanium C++ ABI}}</ref> <syntaxhighlight lang="C"> char A5_A5_c [5][5]; /* array of arrays of chars */ char *A5_Pc [5]; /* array of pointers to chars */ char **PPc; /* pointer to pointer to char ("double pointer") */ char (*PA5_c) [5]; /* pointer to array(s) of chars */ char *FPcvE(); /* function which returns a pointer to char(s) */ char (*PFcvE)(); /* pointer to a function which returns a char */ char (*FPA5_cvE())[5]; /* function which returns pointer to an array of chars */ char (*A5_PFcvE[5])(); /* an array of pointers to functions which return a char */ </syntaxhighlight> The following declarations involving pointers-to-member are valid only in C++: <syntaxhighlight lang="Cpp"> class C; class D; char C::* M1Cc; /* pointer-to-member to char */ char C::*A5_M1Cc [5]; /* array of pointers-to-member to char */ char* C::* M1CPc; /* pointer-to-member to pointer to char(s) */ char C::** PM1Cc; /* pointer to pointer-to-member to char */ char (*M1CA5_c) [5]; /* pointer-to-member to array(s) of chars */ char C::* FM1CcvE(); /* function which returns a pointer-to-member to char */ char D::* C::* M1CM1Dc; /* pointer-to-member to pointer-to-member to pointer to char(s) */ char C::* C::* M1CMS_c; /* pointer-to-member to pointer-to-member to pointer to char(s) */ char (C::* FM1CA5_cvE())[5]; /* function which returns pointer-to-member to an array of chars */ char (C::* M1CFcvE)() /* pointer-to-member-function which returns a char */ char (C::* A5_M1CFcvE[5])(); /* an array of pointers-to-member-functions which return a char */ </syntaxhighlight> The <code>()</code> and <code>[]</code> have a higher priority than <code>*</code>. <ref>Ulf Bilting, Jan Skansholm, "Vägen till C" (the Road to C), third edition, page 169, {{ISBN|91-44-01468-6}}</ref>
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)