IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 指针注意事项 -> 正文阅读

[C++知识库]指针注意事项

? ?但是有一个特例,那就是赋值0的时候,这个时候表达的含义是空指针,比如:

  1. int *ptr;
  2. ptr = 0; //这个是可以的

因此:

在这个程序中str1[0] = 'A'的语句将会正确执行,而str2[0] = 'B'的语句将会引发程序异常

这是因为str2仅存储了字符串常量Hello的地址,常量数据是只读的,操作系统不允许对其进行修改。

str1虽然也是使用字符串常量进行初始化的,但采用的是复制的方式,即将字符串常量复制到str1的内存位置上,这个时候str1就和原来的常量没有关系了,可以任意使用。

  • 注意:与其他变量一样,没有初始化或者赋值的指针变量存的值是随机的,如果此时直接使用*运算符,则会因为访问了不属于程序的内存位置而发生异常。也就是所谓的访问越界
  • 指针相关运算符的优先级

    指针相关的运算符,优先级从高到底依次是:

  • 后置自增自减运算符。

  • 前置自增自减运算符,取地址运算符,指针运算符。

  • &*ptr = &(*ptr)

  • *&a = *(&a)

  • (*ptr)++不等于*ptr++

  • #include <iostream>
    using namespace std;
    //反转数组中的元素,参数为数组的第一个和最后一个元素
    void Reverse(int *start,int *end)
    {
    	/**********   Begin   **********/
    int n = end - start + 1;
    for(int i = 0 ; i < n/2 ; i++)
    {
    	int t = *start;
    	*start = *end;
    	*end = t;
    	start ++;
    	end --;
    }
    	
    
    	/**********   End   **********/
    }

  • *++p相当于a[++i],先将p自加,再作*运算。

  • *--p相当于a[--i],先使p自减,再作*运算。

  • *p++相当于a[i++],先做*运算,再将p自加。

  • *p--相当于a[i--],先做*运算,再将p自加

  • //字符指针,复制字符串
    char a[] = "Hello World",b[20]; //这两个是字符数组
    char *pa = a, *pb = b; //这两个是字符串指针
    while(*pa != '\0')
    {
        *pb = *pa;
        pa++; //指针自增
        pb++;
    }
    *pb = '\0'; //别忘了在字符串最后加上\0
    cout << pa << endl;
    cout << pb << endl;

  • 如果你观察细致的话,就会发现cout对待字符指针与对待其他指针是不一样的,它会直接输出字符串的内容,如果想输出字符指针的地址值,则需要强制类型转换

  • char str1[] = "Hello";
    char *str2 = "Hello";
    str2[0] = 'B'; //别忘了指针也是可以使用[]运算符的
    str1[0] = 'A';

数组变量的类型

之前我们说过数组变量可以看成是一个指向数组第一个元素的指针,但是它与指针还是有差别的。

对于一个数组int arr[10]来说,arr的类型不是int*,而是**int[10]**,这样就产生一个问题,比如:

int *ptr; int arr[4];
cout << &arr << endl; //&arr的类型则是int(*)[4] cout << &arr + 1 << endl;
cout << &ptr << endl; //&ptr的类型是int**

? ? ? ?得到的结果是:??0x62cc3c

??? ? ? ? ? 0x62cc4c

?? ? ? ? ? ?0x62cc4c

? ? ? ? ? ??0x62cc50

可以注意到,&arr + 1增加 的地址值是16,这是因为**int[4]类型**的长度是4 * 4 = 16字节。

这一点,从**sizeof运算符**上也可以体现出来,比如:

int *ptr;
int arr[4];
cout << sizeof(ptr) << endl << sizeof(arr) << endl;

得到的结果是: 4 16

二维数组

  • int arr[2][3];
    int *p1 = arr; //错误,类型不匹配
    int (*p2)[3] = arr; //正确。但是注意:int *p2[3]不等于int (*p2)[3],前者是一个长度为3的数组,数组的每一个元素是int*的指针
    cout << arr << endl;
    cout << arr + 1 << endl;
    cout << p2 << endl;
    cout << p2 + 1 << endl;

  • 总的来说,以数组int a[4]为例,有这三条规律:

  • 数组名可以看做是指向数组第一个元素的指针。

  • &a + 1将跨越16字节,相当于把a的管辖范围上升了一个级别。

  • *a等价于a[0],相当于把a的管辖范围下降了一个级别。

  • 之前说到数组作为形参时,第一个维度是可以省略长度的,这实际上是因为数组形参会被变成其元素指针类型,比如:

    void Func(int a1[],int a2[][10]); //等价于 void Func(int *a1,int (*a2)[10])

  • void Size(int arr[10][10])
    {
        cout << sizeof(arr) << endl;
    }
    int main()
    {
        int arr[10][10];
        Size(arr);
        cout << sizeof(arr) << endl;
    }

    输出 4

    • 400

    • 4是因为输出的是指针,而400则因为输出的是数组

  • int a;
    const int b = 0; //一个整型常量
    const int *p1 = &b; //常量指针
    p1 = &a; //正确
    *p1 = 0; //错误
    int * const p2 = &b; //指针常量,只能初始化
    p2 = &b; //错误
    p2 = &a; //错误
    *p2 = 0; //正确
    const int * const p3 = &a; //指向常量的指针常量,等于上面两种之和

    常量指针和指针常量

  • 常量指针说的是指向一个常量的指针,用于保证所指内容不被修改,但是指针本身是可以被修改的,而且不仅可以指向const常量b,也可以指向变量a;

  • 指针常量只能初始化,可以改内容,不能改指针本身;

  • 指针能作为函数参数,自然也能作为函数的返回值。不过需要注意的是,返回的指针不应该指向函数的局部变量,因为局部变量只在函数这一次被调用期间有效,如果返回了指向局部变量的指针,又在之后的程序中访问了这个指针所指的内容,就会访问越界,可能会引发程序异常

  • 静态局部变量与非静态局部变量的区别在于,在函数结束后,静态局部变量依然存在,而且在下次执行函数时使用的仍然是同一个变量。但需要注意的是,它只进行一次初始化,之后调用函数时会跳过初始化的语句

 
  1. char s[10] = "China";
    char *sptr = s;
    cout << sptr;
    
    
    cout << *sptr ;// 只输出C

这条语句将输出字符串“China”。之前学习字符数组时应该知道,语句cout << s;会输出数组 s 中存储的整个字符串,实际上 C++ 在使用 cout 输出 char 类型指针时,不是输出字符指针的值(地址),而是输出从该地址开始的字符串(逐个输出一个个字符,直到碰到 ‘\0’ 为止)。所以cout << sptr;cout << s;的作用一样,都是输出字符串“China”。?

如果函数参数传了个指针,返回值也不是指针的话,对指针str++什么的,最后返回到主函数里还是从str[0]开始输出

????????

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-09-04 17:19:43  更:2021-09-04 17:19:51 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/27 20:27:44-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计