C++的指针简明教程

C++的指针简明教程

指针是C和C++语言中非常重要的概念,初学的时候会被指针搞蒙。想学好指针,我的经验是不要试图一开始就想理解指针概念,而是要耐心准确的了解指针的各个方面,这是一个过程,随着学习的深入,自然就知道指针是什么了。

【C++指针(pointer)权威文档

英文 https://en.cppreference.com/w/cpp/language/pointer

中文 https://zh.cppreference.com/w/cpp/language/pointer 】

在C++中,地址和指针是紧密相关的。地址是一个变量或对象在内存中的位置,而指针是一个变量,它存储了一个地址。换句话说,指针是指向一个特定类型的变量或对象的地址。

通过指针,我们可以使用间接的方式访问或修改变量或对象的值。我们可以通过将变量的地址赋给指针来创建一个指针。

在C和C++中,*前后的空格是可选的,而且编译器都会将它们解析为相同的意思。在C++中,声明指针的一般语法格式如下:

type* pointerName;

其中, type 通常是指被指向的数据类型,例如 int, float, char, 或者是结构体或类的名称。

pointerName 是你为指向变量的指针所取的名称,也称为指针变量名,可以是任何有效的标识符。注意指针的名称前缀* 是用于表示它是一个指针的。

以下这些声明是等价的:

int* ptr;

int *ptr;

int * ptr;

int*ptr;

C++中的指针变量和普通变量有很大的不同。

首先,指针变量存储的是内存地址,而普通变量存储的是实际的数据值。指针变量可以用来访问和修改存储在该内存地址中的数据,而普通变量不能。

其次,指针变量可以动态地分配内存,而普通变量的内存大小是在编译时就确定了的。这使得指针变量非常有用,因为它们允许程序在运行时动态地创建和管理内存。

最后,指针变量可以用来传递内存地址,而不是将整个数据复制到另一个变量中。这可以节省内存,并提高程序的性能。

需要注意的是,使用指针变量需要小心,因为它们可以很容易地导致内存泄漏、悬空指针和其他问题。因此,在使用指针变量时应该非常谨慎,并且尽可能使用更安全的方法来处理内存。

C++中,指针是一种特殊的变量,它存储的是另一个变量的内存地址。这使得你可以通过指针间接地访问或修改那个变量的值。

以下是一个简单的示例:

int num = 10; // 定义一个整数变量

int *ptr = # // 创建一个整数指针,指向num的地址

cout << num << endl; // 输出变量的值

cout << &num << endl; // 输出变量的地址

cout << *ptr << endl; // 输出指针所指向的变量的值

cout << ptr << endl; // 输出指针的值,即存储的地址

在上面的示例中,我们使用&运算符获取变量num的地址,并将其赋给指针ptr。我们可以通过*运算符来访问指针所指向的变量的值,如*ptr。

需要注意的是,指针的类型必须与其指向的变量或对象的类型匹配。例如,指向整数的指针必须是int*类型。这是因为在读取或修改指针指向的内容时,编译器需要知道要读取或修改的变量的类型。

定义指针变量时的 * 运算符和使用指针变量时的 * 运算符的含义和作用却是完全不同的

在定义指针变量时,* 运算符用于表示该变量是一个指针变量,即可存储地址的变量。例如:

int* ptr; // 定义一个 int 类型的指针变量 ptr

在使用指针变量时,* 运算符用于访问指针所指向的地址上存储的数据。这个过程通常被称为解引用(Dereferencing)。例如:

int num = 42;

int* ptr = # // 定义一个指向 num 的指针变量 ptr

*ptr = 24; // 在访问指针所指向的地址上的数据,并将其修改为 24

在这个例子中,*ptr 用于访问指针 ptr 所指向的地址上存储的数据 num,并将其修改为 24。

指针变量是一个存储指针的变量,通过指向的地址可以定位到具体的数据。

地址是一个数值,是内存单元的编号,用于确定计算机内存中特定位置的位置。

参加下图:0x231001是指针变量p的地址,0x231007是变量i的地址。指针变量存放的是变量i的地址,也就是指针变量的值。所以p=0x231007,*p=5,&p=0x231001。注意其中地址值是示意性的。

C++的指针简明教程_第1张图片

说明

计算机内存想象成一个巨大的有许多格子储物柜。每个格子都有一个编号——内存地址(常称为地址),我们可以用这个编号来记住我们在放了东西的位置。

定义一个变量,例如:

int i  = 5;

这样就将i 和5关联起来了,i 相当于标签名,对i 的存取操作就是5所在的计算机内存空间存取,5在计算机内存空间的存放位置就是地址。这个地址可以通过&i 获得。【地址值的分配是由计算机系统完成的,不固定。】

定义指针变量

int *p;

给指针变量p赋值

p = &i

就是把变量i 的地址给了p,也常称为p指向i 。这时*p和i 等价——值一样。

上面两句可合写为一句:

int *p = &i;

注意点

(1) 对于上面示例语句,i*p是一样的,&ip是一样的。

(2) 如果*、&在类型说明符之后,则为定义指针、引用;如果出现在表达式中,则为解引用、取地址。

(3) 不允许把一个数赋给指针变量,除指针变量初始化赋值(如int *p = &i;),被赋值的指针变量前不能有*(如*p = &i;是错误的)

演示代码如下:

#include 
using namespace std;

int main() {  
    int a = 10;  
   
    //星号符作为指针类型声明符  
    int * p = & a;  // 声明一个指向整型变量 a 的指针  
    
    // i和*p是一样的   
    cout << "*p = " << * p << endl;  // 输出 10。星号符作为指针解引用运算符
    cout << "a = " << a << endl;  // 输出 10。
    // &i和p是一样的
    cout << "p = " << p << endl;
	cout << "&a = " << &a << endl;     
    
    return 0;  
}

运行之:

C++的指针简明教程_第2张图片

注意,你的运行结果 p和&a显示的地址值是随机的(地址值的分配是由计算机系统完成的,不固定),但两者值相等。

下面是一些常见的指针操作:

1.声明指针:可以使用"*"运算符来声明一个指针变量,其指向的是某个数据类型的地址。例如:

int* ptr; // 声明一个指向int类型数据的指针ptr

2.获取地址:可以使用"&"运算符获取某个变量的地址,将其赋值给指针。例如:

int num = 10;  // 定义一个整型变量num

int* ptr = #  // 定义一个指向num的指针ptr

3.解引用操作:使用解引用运算符"*"可以获取指针所指向的变量的值。例如:

int num = 10;

int* ptr = #

std::cout << "The value of the variable pointed by ptr is: " << *ptr << std::endl; // 输出:10

4.指针算术运算:指针可以进行加、减、自增、自减等算术运算。例如:

int arr[] = {1, 2, 3, 4, 5};

int* ptr = arr; // 将指针指向数组首元素

std::cout << "The first element of the array is: " << *ptr << std::endl; // 输出:1

ptr++; // 将指针指向下一个元素

std::cout << "The second element of the array is: " << *ptr << std::endl; // 输出:2

5.数组和指针:数组名本身就是一个指针,指向数组的首元素。因此,可以使用指针来操作数组(例如上面的例子),也可以使用数组名来操作数组。例如:

int arr[] = {1, 2, 3, 4, 5};

std::cout << "The first element of the array is: " << arr[0] << std::endl; // 输出:1

std::cout << "The second element of the array is: " << *(arr+1) << std::endl; // 输出:2

6.指针和字符串:指针可以用来处理字符串,因为指针可以指向字符数组的第一个元素。通过指针,我们可以访问和操作字符串中的字符。下面是一个示例,演示了如何使用指针处理字符串:

#include 
#include 
using namespace std;

int main() {
    string str = "Hello";  // 字符串使用string类型表示
    char *ptr = &str[0];   // 通过指针获取字符串的第一个字符

    // 通过指针遍历字符串并打印每个字符
    while (*ptr != '\0') {
        cout << *ptr << " ";
        ptr++;  // 指针移到下一个字符位置
    }

    cout << endl;

    int a = 10;
    int& ref = a;  // 引用引用变量a

    cout << "a = " << a << endl;
    cout << "ref = " << ref << endl;

    ref = 20;  // 通过引用直接操作变量a的值
    cout << "a = " << a << endl;

    return 0;
}

7.指针和函数:

以下是一些指针和函数的常见用法:

指针作为函数参数:将指针传递给函数,允许函数修改指针指向的变量。例如,使用指针实现一个交换两个整数的函数:

void swap(int* a, int* b) {

    int temp = *a;

    *a = *b;

    *b = temp;

}

函数返回指针:函数可以返回指针,指向函数内部创建的动态对象。例如,实现一个创建整数对象并返回其指针的函数可以写为:

int* create_int(int value) {

    int* ptr = new int(value);

    return ptr;

}

以上是一些常见的指针操作。除此之外,还有一些指针操作,例如,动态内存分配和释放:可以使用“new”运算符在堆上分配一块内存,并返回该内存块的首地址。例如:

int* ptr = new int; // 在堆上分配一个int类型的内存块,并将其地址赋给指针ptr

*ptr = 10; // 给该内存块赋值

std::cout << "The value of the variable pointed by ptr is: " << *ptr << std::endl; // 输出:10

使用“delete”运算符来释放在堆上分配的内存。例如:

int* ptr = new int;

// 做一些操作

delete ptr; // 释放ptr所指向的内存块

需要注意的是,指针操作容易引起内存泄漏和悬空指针等问题,在使用指针时,需要注意内存的分配和管理。

再看使用指针的一个简单例子:

#include 
using namespace std;

int main()
{
  int num = 10;
  int *ptr = # // 定义一个指向整型变量num的指针ptr,&num是num的地址

  cout << "num的值为:" << num << endl; // 输出变量num的值
  cout << "指针ptr所指向的变量的值为:" << *ptr << endl; // 输出指针ptr所指向的变量的值
  cout << "变量num的地址为:" << &num << endl; // 输出变量num的地址
  cout << "指针ptr所存储的地址为:" << ptr << endl; // 输出指针ptr所存储的地址

  return 0;
}

运行结果:

num的值为:10
指针ptr所指向的变量的值为:10
变量num的地址为:0x23fe1c
指针ptr所存储的地址为:0x23fe1c

在这个例子中,我们定义了一个整型变量num,并将它的值设置为10;接着我们定义了一个指向num的指针ptr,并将它的值设为num的地址。我们使用了&运算符获取num的地址。然后通过指针ptr,我们输出了num的值,以及指针ptr的存储地址(ptr自己的地址)和所指向的变量的地址(即num的地址)。最后,返回0以结束程序。需要注意的是,变量的地址通常是由操作系统和运行时环境自动管理的,因此它们通常不是固定不变的,如在不同的计算机上显示的不同值是正常的。

 C++指针(pointer)介绍https://blog.csdn.net/cnds123/article/details/108981367 

C++指针(这是一篇正经知识总结)https://zhuanlan.zhihu.com/p/517099946

你可能感兴趣的:(C,C++学习,c++,开发语言)