C++(二十二) — 指针变量、函数指针、void指针

1、指针变量

(1)指针变量必须在初始化后才可以正常使用,初始化就是给他分配一个有效的数据地址。

  先初始化,后使用。

(2)指针可以进行加减运算,++ 或者 --:将指针的位置向前或者向后移动一个数据单元(char是一个格,int 是4个格子)。

(3)指针之间直接相加没有意义,但相减是求出:两个指针间能存放几个指定类型的数据,不是地址值的具体差值。

(4)不同类型指针之间,不可以相互赋值。

(5)动态内存的申请和释放

// 申请一个内存空间地址给一个指针
    int *pi = 0;
    pi = new int(10);
    cout << *pi << endl;
    delete pi;

    // 申请动态的整型数组,
    int *piarray = 0;
    piarray = new int[10];
    delete[] piarray;

 2、函数指针

  函数指针是指向函数的指针变量。 因而“函数指针”本身首先应是指针变量,只不过该指针变量指向函数。程序在编译时,每一个函数都有一个入口地址,该入口地址就是函数指针所指向的地址。很多c++泛型算法以及linux库函数经常见到函数指针的使用。

// 声明一个函数类型
typedef void (myTypeFunc)(int a, int b);
// myTypeFunc *myfuncp = nullptr;  // 定义一个函数指针,指向函数入口地址

// 声明一个函数指针类型
typedef void (*myPTypeFunc)(int a, int b);
// myPTypeFunc myfuncp = nullptr;  // 通过   函数指针类型  定义了一个函数指针

// 定义一个函数指针变量
void(*myVarPFunc)(int a, int b);

   函数重载和函数指针,一起使用时,定义的函数指针会根据定义的参数类型,选择正确的重载函数。

  typedef是在计算机编程语言中用来为复杂的声明定义简单的别名,它与宏定义有些差异。它本身是一种存储类的关键字,与auto、extern、mutable、static、register等关键字不能出现在同一个表达式中。

//对复杂变量建立一个类型别名的方法很简单,你只要在传统的变量声明表达式里用类型名替代变量名,然后把关键字typedef加在该语句的开头就行了。
int *(*a[5])(int, char*);
//pFun是我们建的一个类型别名
typedef int *(*pFun)(int, char*);
//使用定义的新类型来声明对象,等价于int* (*a[5])(int, char*);
pFun a[5];


void(*b[10]) (void(*)());
//首先为上面表达式加粗部分声明一个新类型
typedef void(*pFunParam)();
//整体声明一个新类型
typedef void(*pFun)(pFunParam);
//使用定义的新类型来声明对象,等价于void (*b[10]) (void (*)());
pFun b[10];

3、void 类型指针

(1)无类型指针:void *pi,也指向内存地址,但不指定这个地址单元内的数据类型。

  不可以直接赋值给其他类型的指针;访问内存数据时,必须进行强制转换,才可以间接访问内存数据。

  不会单独使用,只是作为指针类型转换的中介。比如:通过内存区域的复制函数:memcpy()。原理:将某种类型数据的地址转换 void 指针,进行复制后,再强制转换为原理的地址类型。

   //memcpy()函数的原型,参数:源地址指针、目标地址指针、复制字节数
    // 接受的参数是:任意类型的实参地址指针,void 类型;
    // 返回的也是 void 类型目的地址指针,可以赋值给任何类型的指针。
    void *memcpy(void *dest, const void *src, size_t count);

(2) memcpy()通用复制函数的使用,实例:

#include <iostream>
using namespace std;
#include <string.h>

void main()
{
    // memcpy()通用复制函数的使用
    char src[10] = "012345678";
    char dest[10];
    char* pc = (char*)memcpy(dest, src, 10);  //复制字节数据
    cout << pc << endl;

    int s1[3] = { 1,2,3 };
    int d1[3];
    int *pi = (int*)memcpy(d1, s1, 12);
    cout << *pi << "   " << *(pi + 1) << "   " << *(pi + 2) << endl;

    system("pause");
}

(3)显示字符指针的内容

  使用 cout 输出字符指针的地址值,而不是内容。

    char *pch = "hello c++";
    cout << pch << endl;  // hello c++
    cout << *pch << endl; // h
    cout << (void*)pch << endl;// 输出的内存地址    

  对于单个字符的处理:

   char a = 'h';
    char *pch1 = &a;
    cout << &pch1 << endl;  // 输出 pch1 的地址
    cout << *pch1 << endl; // h
    cout << (void*)pch1 << endl;// 输出的内存地址,即 pch1 中保存的地址的值

 

posted @ 2018-12-20 21:10  深度机器学习  阅读(1750)  评论(0编辑  收藏  举报