zoukankan      html  css  js  c++  java
  • C++中的指针,指针函数和函数指针

    指针是C或C++中的一大难题,因此弄懂指针对C和C++的学习有很大的帮助,最近一直在研究指针,因此写一篇随笔把心得记录一下。

    简单来说指针也是一种变量,只不过指针变量所存储的不是我们直观上看到的,而是内存中的地址。如:

    我声明了一个整型变量a并初始化为5,声明一个整型指针变量b,并且把a的地址赋给它,因此如果我们直接输出b的话就会得到a的地址,而输出*b就会得到a的值。

    注意我的声明语句, int *b; int说明这是整数类型的变量,而*表明这是一个指针变量,合起来就是b是一个整型指针变量,变量名是b而不是*b.这一点很重要。

    因此指针变量的声明方法为:

    1 type *variableName;

    type是数据类型,variableName是变量名。

    这是很简单的一个指针变量的例子,复杂一点的话,我们看看另一种类型的指针:指向指针的指针。如:

     1 #include <iostream>
     2 
     3 using namespace std;
     4 
     5 int main() {
     6     int num = 5;
     7     int *a = &num;
     8     int **b = &a;
     9     cout << b << " = " << &a << endl;
    10     cout << *b << " = " << a << endl;
    11     cout << **b << " = " << *a << endl;
    12     return 0;
    13 }

    上例中我先生命了一个int并初始化为5,然后声明一个指针变量a并把num的地址赋值给它,然后再声明一个指针变量b并把a的地址赋值给它,分析一下上述程序会输出什么呢?

    首先第一行输出,b=a的地址,因为我们赋值的时候就是这么赋值的,这很好理解。

    第二行输出num的地址=num的地址,为什么呢?我们看看,a的值是什么?没错,是num的地址,那么*b是什么?当然就是a的地址存储的东西,那是什么呢?不就等于a吗?

    第三行输出5=5,首先*b = &num, 那么*(*b)不就是&num中存储的东西吗?那不正是num,所以输出5=5。

    还有一个要点就是数组,数组名本身就是一个指针。

     1 #include <iostream>
     2 
     3 using namespace std;
     4 
     5 int main() {
     6     int a[5] = {1, 2, 3, 4, 5};
     7     int *b = a;
     8     cout << a << endl;
     9     cout << b << endl;
    10     return 0;
    11 }

    运行程序可以看到输出两行一样的地址。

    二维数组稍有不同,不同点在于二维数组本身是一个指针数组:

     1 #include <iostream>
     2 
     3 using namespace std;
     4 
     5 int main() {
     6     int a[2][3] = {{1, 2, 3}, {4, 5, 6}};
     7     int (*b)[3] = a;
     8     int *c = a[0];
     9     cout << a << " " << b << endl;
    10     cout << *(a + 1)[0] << " " << *(b + 1)[0] << endl;
    11     cout << *c << endl;
    12     return 0;
    13 }

    b和c的区别在于b是指针数组,包括了(*b)[0]、(*b)[1]、(*b)[2],而c只是一个指针变量,指向数组a的第一个元素的位置。

    如图所示:(多维数组同理)

    然后我们再看看什么是指针函数。指针函数的定义和指针变量差不多,如

    1 int func1();      // 声明一个函数,返回值为int类型
    2 int *func2();    // 声明一个函数,返回值为int类型指针,指向一个int的地址

    我们可以看一个例子:

     1 #include <iostream>
     2 
     3 using namespace std;
     4 
     5 
     6 // 指针函数
     7 int *square(int &a) {
     8     int *s = new int;
     9     *s = a * a;
    10     return s;
    11 }
    12 
    13 int square1(int &a) {
    14     int s1 = a * a;
    15     return s1;
    16 }
    17 
    18 int main() {
    19     int num = 5;
    20     cout << "invoke square:" << endl;
    21     cout << *square(num) << endl;    // 可以理解为cout << *s << endl;
    22     cout << endl;
    23     cout << "invoke square1:" << endl;
    24     cout << square1(num) << endl;
    25     cout << endl;
    26     return 0;
    27 }

     上述程序会输出:

    invoke square:
    25
    invoke square1:
    25

    可以看出,指针函数的用法和指针变量差不多,只不过多了参数(不一定有参数,但函数名后面的括号一定不能漏)
    然后我们再看看函数指针,函数指针也是一个指针变量,与普通的指针变量不同的是它指向的是一个函数的地址,如:
    #include <iostream>
    
    using namespace std;
    
    
    // 指针函数
    int *square(int &a) {
        int *s = new int;
        *s = a * a;
        return s;
    }
    
    int square1(int &a) {
        int s = a * a;
        return s;
    }
    
    int main() {
        int num = 5;
        int *(*pSquare)(int &a);
        int (*pSquare1)(int &a);
        pSquare = square;
        pSquare1 = square1;
        cout << "invoke square:" << endl;
        cout << *(*pSquare)(num) << endl;
        cout << endl;
        cout << "invoke square1:" << endl;
        cout << (*pSquare1)(num) << endl;
        cout << endl;
        system("pause");
        return 0;
    }

    对比一下pSquare和pSquare1我们会发现区别,pSquare是一个指向指针的指针,而pSquare1是一个指向函数的指针,所以pSquare与square搭配,pSquare1与square1搭配。

  • 相关阅读:
    堆和栈的区别(转)
    conversion to dalvik format failed with error 1的解决办法
    eclipse最实用快捷键
    java socket编程(转)
    Android 面试总结
    Android横竖屏总结(转)
    Android布局文件属性笔记(转)
    常用数据结构有哪些(转)
    经常用到的Eclipse快捷键(转)
    url编码转换
  • 原文地址:https://www.cnblogs.com/zhuangshq/p/5122910.html
Copyright © 2011-2022 走看看