C语言进阶:指针的进阶(1)
目录
- 指针进阶
- 字符指针
- 字符指针的作用
- 字符指针的特点
- 指针数组
- 指针数组的定义
- 指针数组的使用
- 总结
指针进阶
我们在初阶时就已经接触过指针,了解了指针的相关内容,有:本章节在此基础上,对C语言阶段指针进行更深层次的研究。
【C语言进阶:指针的进阶(1)】指针定义:指针变量,用于存放地址。地址唯一对应一块内存空间。
指针大小:固定32位平台下占4个字节,64位8个字节。
指针类型:类型决定指针±整数的步长及指针解引用时访问的大小。
指针运算:指针解引用,指针±整数,指针-指针,指针关系运算。
字符指针
字符指针,存入字符的地址,类型为
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)); //eprintf("%s\n", pc); //helloprintf("%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"); //1elseprintf("str1 != str2\n"); //2if (str3 == str4)printf("str3 = str4\n"); //3elseprintf("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,就是得到每个字符串的起始地址,分别向后访问。从这里也可以看出数组和指针的关系,我愿称之为*和[]的爱恨情仇!
总结 本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!
推荐阅读
- 【生信技能树】R语言练习题|【生信技能树】R语言练习题 - 中级
- 一起来学习C语言的字符串转换函数
- C语言字符函数中的isalnum()和iscntrl()你都知道吗
- C语言浮点函数中的modf和fmod详解
- C语言中的时间函数clock()和time()你都了解吗
- C语言学习|第十一届蓝桥杯省赛 大学B组 C/C++ 第一场
- 推荐系统论文进阶|CTR预估 论文精读(十一)--Deep Interest Evolution Network(DIEN)
- C语言解方程的根和判断是否是闰年
- C语言的版本比较
- 普通人进阶的三个过程-很多人都知道,但却本末倒置