answersLogoWhite

0

What is pointer to function in c?

Updated: 8/10/2023
User Avatar

Wiki User

14y ago

Best Answer

Accessing data by their address. A good example is parameter argv of function main.

1. Easy access

2.To return more than one value from a function.

3. To pass as arguments to functions. For eg. consider the following structure

struct student

{

char name[10];

int rollno;

};

If you pass this structure object as argument to function then, 14 bytes(10+4) of memory will be passed to the function. Instead, if you pass the pointer to the structure as argument then only 4 bytes (or 8 bytes)of memory will be passed to the function.

User Avatar

Wiki User

12y ago
This answer is:
User Avatar
More answers
User Avatar

Wiki User

14y ago

Pointer in C is Memory Reference. It stores memory address of any variable, constant, function or something you later use in your programming. Pointer basically used to ease the referencing of variables and others or in polymorphism and inheritance.

This answer is:
User Avatar

User Avatar

Wiki User

9y ago

A pointer is a variable or constant that is used to store a memory address and that allows indirect access to the data stored at that address. In order to understand how pointers work you must first understand how computer memory works.

When we think of memory we often think of RAM - physical memory. However, modern operating systems allocate memory from a virtual address space rather than from the physical address space. The virtual address space is a fixed size which is entirely dependent upon the architecture, such that a 32-bit system is capable of addressing up to 4,294,967,296 bytes of memory and therefore has a 4GB virtual address space. Even if the system has less than 4GB of physical memory, the virtual address space ensures that 4GB is always available (if it has more than 4GB, only 4GB will be accessible). In order to address more than 4GB of memory, you must use a system that uses more address bits, such as a 64-bit operating system. 64 bits increases the virtual address space to a staggering 18,446,744,073,709,551,616 bytes and, since that's far more memory than physically exists on the planet, virtual memory is essential in a 64-bit system.

The operating system maps these virtual addresses to physical addresses, swapping data in and out of physical memory to a paging file (or swap file) as and when required. Since swapping to and from a mechanical hard-drive reduces performance, it pays to have as much physical memory as possible (up to the limits of the architecture) in order to keep swaps to a minimum.

Swapping involves moving the contents of virtual memory in and out of physical memory, thus the physical addresses associated with any running processes and their data could easily change behind the scenes without any warning. That would be disastrous if we were pointing at an address and its content suddenly moved to another address. Fortunately, when we store addresses in pointers we store the virtual address, not the physical address.

Whenever we instantiate a pointer, the compiler automatically sets aside 4 bytes of memory (or 8 bytes on a 64-bit system) to store the pointer's value. In many ways a pointer is not unlike an integer (__int32 or __int64) since memory addresses are just numbers. However a pointer is a data type in its own right and while we could use integers to store memory addresses, a pointer is more specialised and allows us to operate upon the memory in ways that wouldn't be possible with an integer. As an integer data type the value is just a number. But as a pointer data type, it is a memory address.

Although pointers are a data type in their own right, we must still declare the type of memory being pointed at. We do this with the "points-to" operator (*), like so:

char c = 42;

char* p = &c;

Note that we use the address-of operator (&) to assign the address of c to p. If we'd neglected to do this, p would end up pointing at memory address 42 (the value of c) rather than the address c.

Although p is declared as type char (which has length 1 byte), the type refers to the memory being pointed at, not the type of p itself. The variable p is a pointer and is therefore 4 bytes long (we'll assume a 32-bit system for the remainder of this article).

Now that we've stored the address of c in p, we can access c through p by using the indirection operator (*). The indirection operator is the same as the points-to operator which is also the same as the multiplication operator. It may seem confusing at first, but the compiler can work out the meaning of the operator from the context. Note that the indirection operator only works with pointers.

std::cout << *p;

This will print the value 42 because p points to c.

Since p is a variable like any other, it has an address of its own. The following will print all the details relating to p:

std::cout << "Address of p: " << &p << std::endl;

std::cout << "Value of p: " << p << std::endl;

std::cout << "Indirect value of p: " << *p << std::endl;

Note that the address of p and the value of p are both memory addresses. We can confirm that p points to c by printing the address and value of c:

std::cout << "Address of c: " << &c << std::endl;

std::cout << "Value of c: " << c << std::endl;

Note that we cannot use indirection with c because c is not a pointer.

Since p points to c and c is a variable, we can also modify the value of c through p:

*p = 100;

If we now print the value of c we will see that it has changed:

std::cout << "Value of c: " << c << std::endl;

This may seem superfluous since we could have easily modified c directly. That's fine when c is in scope but if we pass c to a function that function would not be able to modify c directly because c would be out of scope. This is because when we pass variables to functions, by default they are passed by value. That means the function will work with a copy of c, not c itself. Thus any changes made to the copy will not be reflected in c - they are separate variables. However, sometimes it would be useful to allow a function to modify a variable and that's where pointers come in. Pointers make it possible to pass variables by reference rather than by value:

void square(char* p) { *p *= *p; }

In order to invoke this function we must pass the address of c rather than the value of c. As you already know, we obtain the address of c using the address-of operator:

char c = 42;

square (&c);

If we now print the value of c we will find it has changed to 84.

Note that when we pass by reference we are passing the address of c rather than its value. The square function assigns the address it receives to the pointer variable p. In other words, p is assigned a copy of the address, so we're not actually passing by reference at all - we're actually passing a memory address by value.

At this stage it is important to recognise the difference between pointers and references in C++. In C, a pointer and a reference were exactly the same thing so there was no distinction. Hence when we indirectly access a value through a pointer we are said to be dereferencing the value of the pointer. But in C++ a reference is something else entirely. References work much like pointers insofar as a reference is just a memory address, however pointers have an address of their own while references do not. A reference is merely an alias for an object.

To understand how references work, let's change our square function to accept a reference rather than a pointer:

void square(char& r){ r *= r; }

To invoke this function we do not need to pass the address of c, we simply pass c itself:

square (c);

We're now passing c by reference because the function accepts a reference named r. The function therefore assigns c to reference r, thus r becomes an alternate name for c. Note that the function body is much simpler because we no longer need to use indirection. Anything we do to r we do to c, because r is an alias for c. If we were to examine the address of r we'd find it had the same address as c. Remember: references are not variables - they have no address of their own.

Although references are often implemented as pointers this is only of concern to the creators of C++ compilers. As programmers, we must keep the concept of references and pointers completely separate.

Generally speaking, references are much easier to work with because it is no different to working with the instance itself. That is, c is also a reference - an alias for the memory occupied by the char. Thus when all references to an object fall from scope, the object is automatically destroyed for us. By contrast, if we point to an instance that has no reference (a dynamic object), we must manually release the memory being pointed at before the pointer falls from scope. If we lose track of the pointer's value, the memory occupied by the object cannot be released, resulting in a memory leak that cannot be recovered until the program terminates. However, while pointers add a level of complexity we don't get with references, pointers are more flexible. For one thing, references cannot be NULL - they must always refer to something valid. For another, references cannot be reassigned once instantiated. That is, we can assign new values to a reference but we cannot assign other references to them. Once assigned, they always refer to the same object. Pointers can be reassigned (unless they are declared constant, of course) thus the same pointer can refer to any object of the same type. Pointers can also be NULL.

Nullifying a pointer is vital when the pointer is not in use. When you instantiate a pointer you must initialise it with a valid memory address. If you fail to do so, the pointer's value will contain whatever was in memory at the time it was instantiated and could therefore point anywhere, with disastrous results should you attempt to access that memory. Some compilers will initialise pointers to an arbitrary but invalid address by default. Therefore it's important to initialise your pointers when you instantiate them. If you cannot assign a valid address (because no object yet exists), assign the NULL value (zero). Address zero is not accessible to any program so as long as you initialise your pointers before using them, you need only check if a pointer is non-zero to ensure it is valid. If it is zero then it has been initialised, but it does not point at anything in particular.

By the same token, as soon as you are finished with a pointer, always reassign it if you can, otherwise nullify it, even if the pointer would fall from scope anyway. This is simply good housekeeping because if you later decide to extend the code and thus prolong the scope of your pointer, zeroing the pointer now means you won't forget to do it later. Remember that pointers are your responsibility, not the compiler's responsibility. To minimise the problems associated with pointers, use references whenever possible and only use pointers when you actually need the additional flexibility they offer.

Thus far we've barely scratched the surface of pointers. Although references are simpler to work with, they do not allow us to create dynamic objects on the heap. This is where the C++ new operator comes in because the new operator returns a pointer, not a reference. This is because references cannot be NULL but if there's not enough free memory of the required size to instantiate a dynamic object, a NULL reference would invalidate our program. If the returned pointer is non-NULL we can be sure the allocation succeeded and we have a valid object on the heap.

Once you have a pointer it can be tempting to reference the object being pointed at. This is unwise if the reference is within the same scope as the pointer because once you delete the object being pointed at through the pointer, your reference will no longer be valid. Remember, references cannot be reassigned and cannot be NULL, but if they refer to memory that has been deleted you immediately invalidate your program. The best place to use references to dynamic objects is in functions. In this way you can instantiate objects using a pointer and then pass the pointer to functions that accept a reference (by passing the dereferenced pointer). When the function returns, the function's reference will have fallen from scope, but your pointer remains valid.

Every object has an address in C++. This includes primitive data types (including pointers themselves), user-defined objects and functions. Function pointers make it possible to pass functions to functions. When passing functions by pointer it is important to ensure the functions you point at have the exact same signature and return type, as determined by the pointer's type. However, you can also pass function pointers with variable length argument lists. Passing functions into other functions makes it possible for the receiving functions to alter their behaviour without the need to hard-code all the possible functions it could call.

You can also create arrays of pointers. These are most useful when dealing with large multi-dimensional arrays because rather than allocating the array as a single contiguous block (which may not be possible due to its size) you can split the array into a series of smaller one-dimensional arrays and use array pointers to refer to each dimension. You can still access the array as if it were allocated contiguously. You can also use pointer arrays to remap an existing array, such that a 1*64 array could be remapped to an 8*8 array or a 4*4*4 array, or any other configuration of 64 elements.

In other words pointers allow you to maintain a single set of data that you can simply point at or refer to as the need arises - there is no need to copy data unnecessarily. Using arrays of pointers means that no matter where the objects being pointed to physically reside, you can access them just as if they were allocated contiguously, or you change the sequence simply by swapping pointers around within the array. Swapping pointers is much quicker than swapping values if those values are larger than the size of a pointer or they employ complex copy constructors.

This answer is:
User Avatar

User Avatar

Wiki User

12y ago

You should not know, nor should you care, how a pointer is implemented in C or in C++. All you should know, or care about, is that a pointer is an address value that points to a value of some other type, including another pointer. I will go so far as so state emphatically that you must not care about the actual bit patterns of the underlying "thing" that makes up a pointer because, to do so, introduces platform and implementation sensitivity to your code, and you do not want that. I will flunk any student or fire any programmer that consistently strives to understand how pointers work other than in order to use them or to understand how compilers are written.

The reason for this somewhat militant attitude is that things change. In the Win16 platform, there were near pointers and far pointers; far pointers possessing a 16 bit segment and a 16 bit offset. In the Win32 platform, there are 32 bit flat pointers which cannot be translated between far pointers by any stretch of the imagination.

Also, in some platforms, like Java, pointers are not even pointers; they are handles, and they have an entirely different meaning.

Also, in some platforms, pointers are stored low order byte first (little-endian), while on others, they are stored high order byte first (big-endian). The bottom line is that writing code that depends on the bit configuration of a pointer is unacceptable. Period.

The only thing the language says is that you can add or subtract an offset from a pointer, generating a new pointer that is (offset * elementsize) away from the old pointer, or you can subtract one pointer from another pointer, if and only if they point to the same array, and learn how many elements away from each other they are.

This answer is:
User Avatar

User Avatar

Wiki User

10y ago

About the this Pointer

In C++ there can only ever be one instance of each function. It does not matter if the function is an external function, a static member function, an instance member function, an operator overload or a function override. Although function overrides appear to have multiple instances, each is local to a different namespace (or class), and so each has its own unique signature and is therefore a completely separate function (not a separate instance of the same function).

With only one instance of each function, it would be impossible for an instance member function to know which instance of the class it should operate upon without an implicit this pointer. It's important to note that static member functions do not have a this pointer since they are not members of any instance (they are local to the class, not to an object of the class).

Consider the following minimal example of an instance member function (an assignment operator).

class A

{

int m_data;

public:

A(const int data=0):m_data(data){}

A& operator= (const int);

};

A& operator= (const int rhs)

{

m_data=rhs;

return *this;

}

As is the convention with all assignment operators, it must return a reference to the instance of the class (the object) upon which it was called. We can see that it returns a dereferenced pointer named this, but where exactly does that pointer come from?

The this pointer is a hidden argument which is passed to the function Behind the Scenes at runtime.

Consider the following:

int main()

{

A a;

a = 42;

}

In the above example, 'a' is an instance of the A class to which we've assigned the value 42. In order to better understand how the this pointer works, let us imagine that there were no instance methods at all and that operator overloads were also not allowed. In other words, let's remove all the sugar-coating and revert to C-style function calls, which means we must modify the code as follows:

class A

{

int m_data;

A(const int data=0):m_data(data){}

A& assign(A*, const int);

};

A& A::assign (A* instance, const int rhs)

{

instance->m_data = rhs;

return *instance;

}

int main()

{

A a;

A::assign (&a, 42);

}

Note that we've used the name instance rather than this because this is a reserved name.

The code is clearly not as intuitive as the sugar-coated version. For instance, when we call the assign function, there's absolutely nothing to prevent us from passing a NULL pointer, which would prove disastrous within the function. This is one of the main reasons why the this pointer is passed as a hidden argument: the compiler takes care of it for us and ensures that the correct instance is passed to the function.

But how does the compiler know which instance of the class to pass? That's where instance methods come in. If we were to call the assign function as if it were an instance member method, we'd be calling a.assign(42) rather than A::assign(&a, 42). In other words, the instance to the left of the member-of operator (.) tells the compiler to which instance we are actually referring and automatically passes a pointer to that reference. In C++, references can never be NULL, thus making it impossible to pass a NULL pointer. Thus a.assign(42) automatically translates to a C-style function call, A::assign(&a, 42).

You will notice that the code within the function itself slightly different. Whereas the C-style function call explicitly assigns to instance->m_data, the instance member function implicitly assigns to m_data. This is because the thispointer is implied whenever an instance member function refers to members of the same instance. In other words, m_data=rhs is exactly the same as writing this->m_data=rhs.

Some programmers prefer to explicitly include the thispointer when referring to members of the same instance or when calling methods upon that instance, but it is wholly unnecessary since there is never any ambiguity. The only reason to do so is for absolute clarity, particularly if a method accepts an argument to another instance of the same class. For instance, if you were to implement a swap method as an instance function, you might do so as follows:

A& A::swap(A& rhs)

{

int temp = this->m_data;

this->m_data = rhs.m_data;

rhs.m_data = temp;

}

Why is this a Pointer and not a Reference?

That's a perfectly valid question since references can never be NULL. In operator overloads such as the assignment operator shown above, it would clearly be easier to return this rather than return *this, or to refer to instance members with the member-of operator (.) rather than the pointer-to-member operator (->).

However, C++ evolved from C where there were no references as such (the term reference was simply an alternative name for a pointer, hence the term dereferencing a pointer to obtain the value being pointed at). Thus when C++ was initially developed, there was no concept of references as a distinct entity to a pointer, so this started out as a pointer. References didn't appear until much later when operator overloading was added to the language. Although it could be argued that switching from a this pointer to a this reference might have been a sensible option at that point, any code written prior to that point with explicit this pointers would simply fail to compile. this was felt too high a price to pay, thus the this pointer remains a pointer to this day.

This answer is:
User Avatar

User Avatar

Wiki User

12y ago

type *ptr;

type-data type

*-is dereferencin opterator

ptr- pointer

This answer is:
User Avatar

User Avatar

Wiki User

9y ago

A Pointer is a Variable that holds a memory address, usually the location of another variable in memory. A pointer to pointer is known as double pointer.

This answer is:
User Avatar

Add your answer:

Earn +20 pts
Q: What is pointer to function in c?
Write your answer...
Submit
Still have questions?
magnify glass
imp
Related questions

Pointer to pointer in c?

Usable. A prominent example is param argv of function main.


Which function is used to determine the position of the put pointer in a file in c plus plus?

The function ftell returns the position of the file pointer for a file.


WHAT IS POINTER TO POINTER IN C POINTER?

Pointer in C is Memory Reference. It stores memory address of any variable, constant, function or something you later use in your programming. Pointer basically used to ease the referencing of variables and others or in polymorphism and inheritance.


C program pointers to pointers examples?

Pointer to Pointer is a double pointer, denoted by (**). Pointer stores the address of the variable and pointer to pointer stores the address of a pointer variable and syntax can be given as int **ptr2ptr;


What is an address in C plus plus programming?

An address in C or C++ is the location in memory of an object or function. An address is the contents of a pointer, as opposed to the contents of the memory location pointed to by the pointer.


Give the difference between function and pointer in c?

There is no similarity between the two.


Explain pointer to function with example c language?

It isn't a question, sorry.


How can you declare a pointer function?

*function();this declares a pointer function!


What is the difference bw function pointer and function of pointer?

function pointer is a variable that hold the address of any function which declared in the program but function pointer is the array of the function that accept the run time size of the function.


What is the difference between a function pointer and a pointer to a function?

A pointer to a function is the memory address that stores the address of a function, while the pointer itself is a function pointer.A pointer to a function might be defined as "int (*pf)(int, int);", while to actually point to the function, you would use a function pointer, such as "pf = &func;".


What is the implicit name of the parameter that gets passed into the set method of class in c?

Every non-static member function has a hidden pointer parameter named this which refers to the instance of the class the function was invoked against. For a given class, C, the type of the hidden this pointer is const C* but if the function is declared const, the pointer is const C* const. When referring to any class member, m, from within any non-static member function, this->m is implied.


Why void is used in c language?

void as function return-type means no return value void as function parameter means no parameter void * as pointer type means generic pointer