The basics of programming in c++ for beginners

Pointers to functions

It has been observed, that the pointers can point to a variety of types of objects in the program language C ++. More precisely, to all and on all kinds of objects, Data in the program are.

However, the same objects, as conventional data objects, are functions in a Programme. Hence arises a desire to try to define and use a function pointer. Create this simple program (ex1.cc):

Here, with the function area() all clear: it calculates the area of ​​a circle of radius, who is devoted to her, as a parameter. But later, we declare a variable pointer to a function:

At the time of this announcement, the pointer pfunc It is nothing more, as a certain address in the internal computer representation (4 Byte 32-bit operating system,, 8 Byte 64-bit operating system,). This is exactly the same kind of internal, which has, let us say, a pointer to an integer variable int*.

However, this index has a strictly defined type: a pointer to a function, takes one parameter of type double, and returns a value of type double. But on what specific function pointer points, at its definition - no matter: the index value is not defined.

But the next assignment operator we bind a function pointer to a particular function area(). Absolutely correct would be to record the assignment of function pointer addresses: pfunc = &area. But the C ++ compiler is smart enough, that references the function name in the assignment statement interprets as its address.

Thus entry pfunc = area also absolutely correct. From this point we can use the pointer pfunc to call a function to which it points. To do this, we write the value to which the pointer points *pfunc (operation * in this context it is called dereference pointer).

The parentheses around the dereferenced value pfunc in recording (*pfunc)( r ) necessary for reasons of priority of operations in terms of disclosure. Executing this example:

a pointer to a function, c ++, Programming for beginners, c++

While the use of function pointers did not bring anything fundamentally new in this example,, apart from some syntax intricacies. But in this example, we still only know how to define and use function pointers. And now we can move on to the question of why it is needed and how we can use it.

Supposing, for a large project, we are preparing a series of tests, performed in the process of development and growth of the test project (the so-called test development technology, and very productive). The number of turn-based test in this situation will continue to grow as we move readiness of the base project.

In this situation, we can do so (ex2.cc):

And that's what we have on the performance of:

a pointer to a function, c ++, Programming for beginners, c++

In this listing tests[ ] – this is array function pointers with no parameters and no return value. Beautiful solution, is not it? We can not hesitate to add new features caused by solid test, and all of them will be called in sequence when performing.

We can go even further: if the function is a pointer to a function in an expression, You can pass a function pointer as a parameter to another, embracing function, and the latter will perform in your body function to pass parameters, not knowing what action is performed at the same time.

To illustrate what has been said the program will create the most primitive calculator, performing arithmetic operations on integer operands (ex3.cc):

It performs the actual calculation function calculate(). But she did not "know" anything about the actions carried out and all arithmetic operations: it applies to the 2nd the first one of its parameters 6 functions, which she handed over to the 3rd parameter to perform.

Who does not know about typedef read here.

This code function strtod() – a standard feature of the C library (ANSI C, standard POSIX), which extracts a decimal number from a string, obtained from the standard input stream. In the context of our discussion is interesting because, what:

    • a C ++ program can use the entire set of C library calls;
  • C ++ program using runtime shared C library (.so or .dll), and in the absence of a standard C library, C ++ programs are inoperative.

But back to the calculator shown (its extremely simplified due to the fact, that we do not deal with the problems of input, its format and do not process the user input errors – in real applications so you can not do):

a pointer to a function, c ++, Programming for beginners, c++

Observant reader might have noticed, that the function calculate() despite all their desire and could not perform any of the required arithmetic operations, well as performing these actions function sum(), dif(), I have() and div() described later functions calculate() not visible in the function code calculate().

In this way, We looked at several different occasions, when functions are used in C ++, as data items. They can be combined in arrays, integrated as fields structures, or transferred to other functions as arguments.

All these details and possibilities are realized at the expense of function pointers (Although they may not look as pointers syntax records, due to the intelligent C ++ compiler, who understands the context, that should be used functions addresses).

See also the lesson Pointers to objects

18 thoughts on “Pointers to functions

  1. The extra semicolon in the first listing after the function double area(double R).

    “an address in the internal computer representation”
    Just “an address”, what about this supplement “internal representation”? – it adds something to the point?

    “New in this primert”
    typo.

    “You can pass a function pointer as a parameter to another, embracing function, ”
    What's the function of covering? What it covers?

    “Who does not know about the typedef - read here.”
    Link excellent, but it is better to write about it here (it's not much).

    The last example is dull. IMHO on function pointers have to say about it as a whole (as in the first example Article), Then give an example of a standard function qsort, which takes a pointer to a comparison function. And to complete all something like the search function of the root by bisection (this is a very simple example, and it just as convenient to pass to qsort function as a parameter).

    That is. the user must see that there are pointers to functions and deal with the syntax (In the first example, you can add a description typedef). Then I saw, it really necessary (once used in the standard library). Well, in the end I learned to write the same functions, take other function pointer, as qsort.

    Well, this is IMHO.

    1. > Just "an address", to which this supplement about "internal representation"? - It adds something to the point?

      certainly adds. Because, in terms of typing C, especially C ++, syntactically “simply addresses” or “some addresses” in general there is no (except that except void *). All typed pointers (and the radically differ from each other). And only in the internal machine representation of a pointer to a function, a class method, let us say, и char * – already do not differ, they are simply indistinguishable.

      1. > certainly adds. Because, in terms of typing C, especially C ++, syntactically "simply addresses" or "certain addresses" does not exist at all (except that except void *). All typed pointers … And only in the internal machine representation of a pointer to a function, a class method, let us say, and char * - already do not differ, they are simply indistinguishable.

        Address – even in Africa address, no matter on what you write.

        #include

        int main() {
        int val = 12345;
        int *intp = &val; // type typed pointer
        char *charp; // Another typed pointer
        charp; (char*)INT;

        std::cout << (int) *charp << " " << *(int*)charp << std::endl;
        }

        Here it is shown that an int pointer can be cast to a char pointer.
        Well, then you can refer to at this address data. In the first case, dereferenced pointer char *, so the first byte is selected by the address of val. In the second case, char * is cast to an int * pointer and dereferenced, therefore already taken all 4 bytes.

        Conclusion: 57 12345

        In any case, the addresses in Cu can function as desired. You can take data from any address, read them and write them anything.

        For example you could append to the end of this program, something like:
        *charp; 56;

        std::cout << val << std::endl;

        that is, the address can be replaced with val variable first byte, working with him through a char pointer. And you can not first byte, since in C all is well with the address arithmetic.

    2. > The last example is dull. IMHO on pointers to functions had

      But on this occasion: not “it was necessary to” – and it was necessary to take and how to write your text, and their examples. And do not tell sad “as it should have been”.

      1. I am writing “their texts” :). By criticism calmly. Especially in that, that you have learned can not be obtained.

        >> In the context of our discussion is interesting because, what: … C ++ program using runtime shared C library (.so или .dll), and in the absence of a standard C library, C ++ programs are inoperative.

        “The context of our discussion” – this is “function pointers” and in it we do not wonder what's going on with the shared libraries.

        Especially, that the accuracy of information that may be questionable. You say, that the program is used in C ++ “shared library” C language. term “shared library” suggests, library that is simultaneously used by multiple processes.

        Duck's, The library includes inside each executable file, they do not nifiga “shared”. As they shared can be used for debugging, but with the option of going Releases –always static. Otherwise, your program will not run on your computer, if it is not installed on the same version of the compiler, that you used when assembling the program and will not be prescribed the appropriate paths to your system PATH variable. Or you can, of course, run all programs, written in C ++ from one directory, in which the root place the appropriate .dll / .so, but no one else does

      2. int powr(int op1, int op2)
        {
        int ret = 1;
        while (on 2–) right * = op1;
        return ret;
        }

        This type of construction in the whole degree. Little of, wildly it ineffective and may be replaced by the use of standard function. So it still falls a negative value op2.

        PS. If you write an article about the function pointers in C ++, IMHO it is necessary to tell about std::functional. With an ode to the parties stated in the title of C ++, not his. With another – funtional almost every point of view is better and more convenient. For example, I through it can transmit lambda (Yes, and any other callable object), and through a function pointer – I can not.

        Instead, the author wrote some incorrect information about “shared library”.

      3. I totally agree with the following commentator, lessons you do not get.

  2. int main()
    {
    //…
    return 0; // already 4 This year, an extra string. If the program is not terminated abnormally, * * it automatically returns zero error code. That is. you're here to perform work, that without you the compiler performs

    >> Supposing, for a large project, we are preparing a series of tests, performed in the process of development and growth of the test project (the so-called test development technology, and very productive). … In this situation, we can do so (ex2.cc):

    In this situation, in any case it is impossible to do so, as you write. All your efforts are far from wild “development through testing”. Look at the google test framework or to boost unit test framework or 100500 analogs.

    >>
    for (int i = 0; i > due to the intelligent C ++ compiler, who understands the context, that should be used functions addresses

    Sex articles you talk about “smart compiler”. In reality, there is nothing particularly clever is not – If the function name is not a parenthesis, stopudovo it is not a function call, and a pointer to it. No misrepresent type &I function anywhere but your article has not seen.

    1. Maybe so, but as a beginner, it became clear to me that just the name of the function is essentially the address of the function, because it is clearer in terms of abstract understanding

  3. How difficult it all is I have with these pointers:(
    An interesting lesson and makes a lot of thinking. I guess it's good, but some of the highlights for me have remained unclear. Especially with an array of function pointers, and can anyone answer me through typedef.
    typedef int(*fint_t)(int, int);
    fint_t foper[] =
    {
    summ, diff, much, divd, bals, powr
    };
    Here is the view, that the function of the pointer turns into a type of data?
    Explain, please…

    1. typedef does not introduce a new type of, it only defines short synonym for long writing “a pointer to a function here this type”.
      A more determined array these function pointers (named foper) and he immediately clearly initialized. Because of the size of the array initialization is displayed, then at his description, we can not specify it ([]).

  4. Clear, that sizeof returns the length in bytes, but the condition:
    i < sizeof(tests) / sizeof(tests[0])
    I can not understand. Explain pzhl.

    1. What could be simpler?
      As it happens the number of array elements.
      If an array of 1-byte elements (char[]) It contains 10 elements, it is 10/1 = 10.
      If the 100-byte array elements (structures)It contains 10 elements, it is 1000/100 = … and again 10.

      1. Give plenty of problems were on the topics on this site…thank you for the lessons!

    2. then so , sizeof(tests) returns the amount of memory(call it what you want) which: 1)Used in the array , if it was described like this
      [code] void (*tests[])(void) = {test1 , test2 , test3 , test4}[/code] – here will 4 items. 2)But if you use another ad: [code]void (*tests[5])(void) = {test1 , test2 , test3 , test4}[/code]- here anyway , and the memory allocated for 5 elements , according to this [code]sizeof(tests) / sizeof(tests[0])[/code]
      equal to 5 , but not 4 as one might think. On this better in this case do not specify the size of massiva.Tak in the cycle we will try to call a function from scratch and get a runtime error

Leave a Reply to Dawood Cancel reply

Your email address will not be published. Required fields are marked *