admin 管理员组

文章数量: 887021


2023年12月22日发(作者:命令窗口运行java)

c++指针的用法

C++中的指针是一种特殊的变量,其存储的是另一个变量的地址。通过指针可以直接访问该地址所对应的变量,从而操作它的值。以下是C++中指针的十大常见用法。

AI让生活更美好

分享学习C/C++编程、机器人、人工智能等领域知识。

103篇原创内容

公众号

1

动态内存分配

动态内存分配是指在程序运行时,根据需要动态地分配内存空间。这种分配是在堆上进行的,与静态内存分配(在编译期间就分配好内存)不同。

在C语言中,动态内存分配主要通过malloc()函数和free()函数实现。malloc()函数用于申请一定大小的内存空间,并返回一个指向该空间的指针;free()函数则用于释放已经申请的内存空间,避免内存泄漏。

在C++语言中的动态内存分配是通过new和delete关键字实现的。

动态内存是在程序运行时根据需要分配或释放的内存,相对于静态内存,动态内存在空间使用上更加灵活,但也需要小心使用以避免内存泄漏等问题。

动态内存的基本用法如下:

分配内存:使用new关键字申请一块内存,如:

int* p = new int; // 申请一个int类型的内存块

初始化内存:如果需要,可以使用括号进行初始化,如:

int* p = new int(123); // 申请一个int类型的内存块并初始化为123

访问内存:使用指针访问内存,如:

int* p = new int;*p = 456; // 将指向的内存赋值为456std::cout

<< *p << std::endl; // 输出:456

释放内存:使用delete关键字释放之前申请的内存,如:

int* p = new int;delete p; // 释放内存p = nullptr; // 避

免野指针

需要注意的是,在使用完动态内存后,必须及时释放内存,否则会导致内存泄漏的问题。此外,在释放内存后,最好把指针设置为nullptr,以避免成为野指针。

2

传递参数

指针可以作为函数的参数传递地址,这样在函数内部就可以通过指针来修改原始变量的值。在函数定义中,将指针作为参数声明时需要使用星号(*)来表示该参数是一个指针类型,例如:

void changeValue(int *ptr) { *ptr = 10;}int main() { int

num = 5; cout << "num before function call: " << num << endl;

// 输出 num 的值为 5 changeValue(&num); // 将 num 的地址传递给函数 cout << "num after function call: " << num << endl;

// 输出 num 的值为 10 return 0;}

在上面的代码中,我们定义了一个 changeValue 函数,它的参数是一个 int* 类型的指针。函数内部通过解引用操作符 * 修改了指向的内存空间的值为 10,从而改变了原始变量 num 的值。

在主函数中,我们先输出 num 的初始值为 5,然后调用 changeValue

函数并将 num 的地址作为参数传递进去,最终再次输出 num 的值为

10。

为了避免这种繁琐的用法,其实我们可以使用引用&。

3

数组访问

使用指针可以通过指针算术来访问数组元素,实现更高效的数据结构和算法。指针是一个变量,它存储了另一个变量的地址。在C/C++语言中,数组名本质上是指向数组第一个元素的指针,因此可以使用指针算术来访问数组元素,而无需使用数组下标。

例如,假设有一个int类型的数组a,要访问第i个元素,可以使用以下代码:

int a[100];int i = 5;int *p = &a[0]; // p指向a的第一个元素int x = *(p + i); // 访问a[i]

这里,我们定义了一个指向a的第一个元素的指针p,并使用指针算术将指针p移动i个位置以访问a[i]。由于指针算术比数组下标运算更快,因此在某些情况下,使用指针可以提高程序的效率。

4

字符串处理

指针可以方便地操作字符串。在C/C++语言中,字符串是以字符数组的形式存储的,而指针可以方便地访问和操作数组内的元素。以下是几个常用的字符串操作:

查找子串:可以使用strstr()函数来查找某个子串在一个字符串中的位置。

比较字符串:可以使用strcmp()函数来比较两个字符串是否相等。

复制字符串:可以使用strcpy()函数来将一个字符串复制到另一个字符串中。

连接字符串:可以使用strcat()函数来将两个字符串连接起来。

下面是一个使用 strstr() 函数的简单例子:

#include #include int main(){ char

str[] = "Hello

World"; char sub[] = "World"; char *pos

= strstr(str, sub); if (pos != NULL)

{ printf("'%s' is found in '%s' at position %ldn", sub,

str, pos - str); } else { printf("'%s' is not found

in '%s'n", sub, str); }

return 0;}输出结果为:

'World' is found in 'Hello World' at position 6

以上代码中,我们定义了一个字符串 str 和一个子串 sub,然后使用 strstr() 函数在字符串 str 中查找子串 sub。如果找到,则打印出子串在字符串中的位置;否则打印出字符串未找到的信息。

5

函数指针

函数指针是指一个指向函数的指针变量,它可以保存函数的地址并且可以在程序运行时动态地调用相应的函数。函数指针的类型由函数的返回值类型和参数列表来决定。

例如,假设有一个函数:

int add(int a, int b) { return a + b;}

那么可以定义一个指向该函数的函数指针变量:

int (*p)(int, int) = add;

这里的 (*p) 表示 p 是一个指向函数的指针变量,后面的 (int,

int) 表示该函数接受两个 int 类型的参数,并返回一个 int 类型

的值。将 add 函数的地址赋给 p 变量之后,就可以通过 p 来调用该函数:

int result = (*p)(3, 4); // 调用 add 函数,返回 7

或者使用更简洁的写法:

int result = p(3, 4); // 调用 add 函数,返回 7

6

指针函数

指针函数是一种返回值为指针类型的函数。我们可以通过指针函数来返回一个指向某个数据类型的指针,这样就可以方便地在程序中进行数据的处理和操作。

在上面的示例中,getArray 函数首先使用 malloc 动态分配了一个大小为 size 的整型数组,并对其进行操作。最后,该函数返回指向该数组的指针。在主程序中,我们可以利用该指针来访问和操作数组中的元素。

需要注意的是,在使用指针函数时,必须要确保所返回的指针指向的内存区域仍然有效,否则可能会导致程序崩溃或者数据损坏等问题。因此,在使用完毕后,必须要及时释放动态分配的内存空间,避免出现内存泄漏等问题。

7

指针数组

指针数组和数组指针都是指针和数组的组合形式,但它们的定义和使用方式有所不同。

指针数组是一个数组,其中每个元素都是指针类型。例如,int

*ptr[10] 定义了一个包含10个元素的指针数组,每个元素都是int类型的指针。这种数组可以用来存储指向不同变量的指针,也可以用来实现多维数组。

例如,以下代码定义了一个指针数组,其中包含三个元素,每个元素都是int类型的指针:

int *ptrArray[3];

8

数组指针

数组指针是一个指针,它指向一个数组。例如,int (*ptr)[10] 定义了一个指向包含10个整数的数组的指针。这种指针可以用来访问数组中的元素,也可以用来传递数组作为函数参数。(这些概念有点绕口,需要理解,不可盲记)

定义一个数组指针可以使用以下语法:

int (*ptr)[3]; // 定义一个数组指针,指向 3 个元素的 int 型数组

这里 (*ptr) 表示 ptr 是一个指针变量,指向某个数组的首地址,

[3] 表示 ptr 指向的数组有 3 个元素。需要注意的是,这里的括号是必须的,因为数组指针的优先级比较低,如果不加括号会出现错误。

9

类的成员指针

类的成员指针是指向类的数据成员或成员函数的指针。可以通过以下方式定义和使用类的成员指针:

定义成员变量的指针

定义成员函数的指针

需要注意的是,类的成员函数指针只能指向非静态成员函数,并且必须使用类对象来调用该成员函数。

10

指针常量与常量指针

指针常量和常量指针是两个不同的概念。

指针常量是指一个指针变量被声明为常量,即该指针变量的值不能被修改,但是它所指向的内存中的值可以被修改。

常量指针是指一个指针变量所指向的内存中的值被声明为常量,即该指针变量所指向的内存中的值不能被修改,但是指针本身的值可以被修改。

需要注意的是,在常量指针中,const关键字位于*之前,表示指针所指向的内存中的值是常量;而在指针常量中,const关键字位于*之后,表示指针本身是常量


本文标签: 指针 使用 函数 数组 指向