C语言进阶:指针的进阶(1)

 更新时间:2021年09月02日 14:18:13   作者:AKA你的闺蜜  
这篇文章主要介绍了C语言指针详解及用法示例,介绍了其相关概念,然后分享了几种用法,具有一定参考价值。需要的朋友可以了解下

指针进阶

我们在初阶时就已经接触过指针,了解了指针的相关内容,有:

指针定义:指针变量,用于存放地址。地址唯一对应一块内存空间。

指针大小:固定32位平台下占4个字节,64位8个字节。

指针类型:类型决定指针±整数的步长及指针解引用时访问的大小。

指针运算:指针解引用,指针±整数,指针-指针,指针关系运算。

本章节在此基础上,对C语言阶段指针进行更深层次的研究。

字符指针

字符指针,存入字符的地址,类型为char *

字符指针的作用

1.指向单个字符变量

char ch = 'w';
const char* pch = &ch;

这种很容易理解,就是指针解引用访问字符变量。

2.指向字符串首字符

char* pc = "hello";
printf("%s\n", pc);

这种是把字符串"hello"放进指针嘛?

其实不然,类似于数组名,该指针存的是常量字符串"hello"的首字符的地址。通过对指针解引用访问首字符地址,从而找到整个字符串。

在这里插入图片描述

char* pc = "hello";
printf("%c\n", *(pc + 1));//e
printf("%s\n", pc);//hello
printf("%s\n", pc + 1);//ello

字符串本质上还是在空间上连续存放,所以指针±整数同样有访问的效果。由此也可以看出%s的用法,把地址给%s会将其后的内容看作字符串并打印直到\0 。(所以我猜测%s的s是string的意思)

字符指针的特点

例题

char str1[] = "hello bit";
char str2[] = "hello bit";
char* str3 = "hello bit";
char* str4 = "hello bit";
if (str1 == str2)
    printf("str1 = str2\n");//1
else
    printf("str1 != str2\n");//2
if (str3 == str4)
    printf("str3 = str4\n");//3
else
    printf("str3 != str4\n");//4

str1(3)==str2(4),比较的是二者其实位置地址是否相同。(地址才是真正判断二者是否相同的要素)

答案是2和3。因为1和2是用字符串初始化数组,3和4是指针指向常量字符串。

str1和str2是普通的数组,是在内存上开辟了两块空间不过存放了一样的数据。
str3和str4指向常量字符串,存放在内存的常量区,是不可被修改且具有唯一性即常量区只存放一个。所以str3和str4指向的都是同一个字符串。

在这里插入图片描述

常量区的存储特点:存放在常量区的数据不可被修改,正因为不可修改所以存一份就够了。后期如果需要,使用的是同一数据。(数据还是同一个数据,只是用不同的指针维护)

小结

1.常量字符串不可被修改,存放在内存的常量区。

2.具有唯一性即常量区只存放一个。

指针数组

指针数组的定义

int arr[10];//整型数组
char ch[5];//字符数组
float f[20];//浮点型数组

可见,元素类型也就是数组的“类型”。

char* pch[5];
int* parr[10];
float* pf[20];

指针数组就是存放指针的数组。

int arr[10];
int* arr[10];

整型数组的数组名arr,即首元素地址,是一级指针。

指针数组的数组名parr,也是首元素地址,不过其首元素为int*类型变量,所以parr就是二级指针。

指针数组的使用

int arr1[] = { 1,2,3,4,5 };
int arr2[] = { 2,3,4,5,6 };
int arr3[] = { 3,4,5,6,7 };
int* parr[] = { arr1,arr2,arr3 };
for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 5; j++) {
        //1.
        printf("%d ", parr[i][j]);
        //2.
        printf("%d ", *(*(parr + i) + j));
    }
    printf("\n");
}

//答案
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
ps:
parr[i] <==> *(parr+i)
*(parr[i]+j) <==> *(*(parr+i)+j) <==> (*parr+i)[j] <==> parr[i][j]

通过指针数组访问整型数组的每个元素。parr[i][j]和*(*(parr+i)+j)本质上是等价的。

const char* pch[] = { "abcde", "bcdef", "cdefg" };
for (int i = 0; i < 3; i++) {
    //1.
    printf("%s", pch[i]);
    //2.
    printf("%s", *(pch + i));
    for (int j = 0; j < 5; j++) {
        //3.
        printf("%c", pch[i][j]);
        //4.
        printf("%c", *(*(pch + i) + j));
    }
    printf("\n");
}

打印字符串使用%s更简单,若要使用%c,就是得到每个字符串的起始地址,分别向后访问。

从这里也可以看出数组和指针的关系,我愿称之为*和[]的爱恨情仇!

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!

相关文章

  • C++多态的示例详解

    C++多态的示例详解

    多态按字面的意思就是多种形态。当类之间存在层次结构,并且类之间是通过继承关联时,就会用到多态。本文将通过三个小案例让大家更深入的了解一下C++的多态,感兴趣的可以了解一下
    2022-06-06
  • vs2020打包生成exe的实现方法

    vs2020打包生成exe的实现方法

    本文主要介绍了Visual Studio Installer Projects插件和第三方软件SetupFactory创建可安装的Windows应用程序包,并最终将其转换为可执行文件的方法,感兴趣的可以了解一下
    2024-12-12
  • C++中NULL与nullptr的区别对比

    C++中NULL与nullptr的区别对比

    nullptr是c++11中的关键字,下面这篇文章主要介绍了C++中NULL与nullptr区别的相关资料,对大家来说还是挺实用的,需要的朋友可以参考下
    2021-05-05
  • 详解C语言中二分查找的运用技巧

    详解C语言中二分查找的运用技巧

    本文主要介绍了二分查找在实际中的应用,通过分析几个应用二分查找的实例,总结下能使用二分查找算法的一些共同点,感兴趣的可以了解一下
    2022-03-03
  • C语言数组元素的循环移位方法

    C语言数组元素的循环移位方法

    今天小编就为大家分享一篇C语言数组元素的循环移位方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-07-07
  • 深入解析C++和JAVA的字符串

    深入解析C++和JAVA的字符串

    这篇文章主要介绍了C++和JAVA的字符串,JAVA 中String 和StringBuffer的区别,需要的朋友可以参考下
    2015-07-07
  • QString的常用方法(小结)

    QString的常用方法(小结)

    这篇文章主要介绍了QString的常用方法(小结),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-12-12
  • 一文详解Qt如何优雅的进行界面布局

    一文详解Qt如何优雅的进行界面布局

    使⽤ Qt 在界⾯上创建的控件, 都是通过 “绝对定位” 的⽅式来设定的,这种设定⽅式其实并不⽅便,尤其是界⾯如果内容⽐较多, 不好计算,所以Qt 引⼊ 布局管理器 (Layout) 机制, 来解决上述问题,需要的朋友可以参考下
    2024-05-05
  • C++设计模式之单例模式详解

    C++设计模式之单例模式详解

    这篇文章主要介绍了C++设计模式之单例模式,本文同时给出了数种单例模式的实现代码,需要的朋友可以参考下,希望能够给你带来帮助
    2021-09-09
  • C++中友元的实例详解

    C++中友元的实例详解

    这篇文章主要介绍了C++中友元的实例详解的相关资料,希望通过本文大家能掌握友元的使用方法,需要的朋友可以参考下
    2017-09-09

最新评论