没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
前言
一直觉得C语言较其他语言最伟大的地方就是C语言中的指针,有些人认为指针很简单,而有些人认为指针很
难,当然这里的对简单和难并不是等价于对指针的理解程度。为此在这里对C语言中的指针进行全面的总
结,从底层的内存分析,彻底让读者明白指针的本质。
我认为C指针应该和C语言中的变量放在一起,因为C指针本质上还是一个变量,但现在大部分教材将其单独
拿出来讲解,这也使得很多初学者认为指针是一个和变量毫无相关的概念。
有人说学会了指针,C语言也就学会一半。为什么说指针难。因为指针与数组相结合就涉及数组指针与指针
数组。指针与结构体结合就涉及结构体指针。指针与字符结合涉及字符指针。指针与const结合涉及常量指针
与指针常量。指针与函数结合涉及函数指针与指针函数,同时也会涉及回调函数。指针和指针结合涉及到二
维指针。
1 指针的定义
我们知道,普通的变量存储的是一个值。而指针变量,它存储的也是一个值,只是这是一个特殊的值:它的值
是另一个变量的地址。
指针的定义形式如下:
其意思就是name是一个指针,它指向的是一个类型为dataype的地址。
指针存储的是一个地址,如果需要获取这个地址对应的内容,可以通过解引用符*获取:
这里需要注意的一点,也是我以前经常迷惑的一点:定义指针时,编译器并不为指针所指向的对象分配空
间,它只是分配指针本身的空间,除非在定义时同时赋给一个字符串常量进行初始化。比如:
上面这个代码段说明了一个极为常见的错误:我们声明了这个变量,但从未对它进行初始化,所以没法预测
12这个值将存储于什么地方。如果变量是静态的,它会被初始化为0;如果变量是自动地,它根本不会被初
始化。无论哪种情况,声明一个指向整型的指针都不会"创建"用于存储整型值的内存空间。
但是, 下面的定义创建了一个字符串常量(为其分配了内存):
并初始化指针时所创建的字符串常量被定义为只读。如果试图通过指针修改这个字符串的值,程序就会出现
未定义的行为。
除了上述的定义是对的外,其他的定义都是错误的,如下:
2 指针的运算
指针 +(-) 整数指针存储的是一个地址,这个地址本质上是一个整数,所以可以加上或减去一个整数。但是它
不是普通的加法或减法,指针加上或减去一个整数结果是另一个指针。但是,运算后的指针指向哪里呢?当
一个指针和一个整数执行算术运算时,整数在执行加法(减法)运算前会根据合适的大小进行调整。这个"合适
的大小"就是指针所指向类型的大小,"调整"就是把整数值和"合适的大小"相乘。
datatype *name;
或
datatype *name = 地址;
int a = 12;
int *pa = &a;
printf("*pa:%u.", *pa); // 输出是12;
*pa = 14; // 此时a的值为14了,因为p指向的是变量a的地址,改变了*p就相当于改变了a变量的值
printf("%d\r\n", a);// 这里将输出14
//指针未初始化
int *a;
//执行这行代码会出异常,因为指针a并未初始化
*a = 12;
char *p = "breadfruit";
float *pip = 3.14; // 错误!无法通过编译
int *p = 10;// 错误!无法通过编译
#include <stdio.h>
运算结果:
由上面的结果可以看到,当对指针pa,pb,pc进行加1时,实际地址增加的是对应类型(即sizeof(类型))的
大小。减法也一样。
指针 - 指针
只有当两个指针都指向同一个数组中的元素时,才允许从一个指针减去另一个指针。两个指针相减的结果是
两个指针之间的元素个数。比如,如果p1指向array[i]而p2指向array[j],那么p2-p1的值就是j-i的值。如果两
个指针所指向的不是同一个数组中的元素,那么它们之间相减的结果是未定义的,也是毫无意义的。
3 指针与数组
3.1 数组指针(指向数组的指针)
数组指针,它是一个指针,指向的是一个数组。即它存的是一个数组变量的地址。所以这个指针每加一步的
步长就是数组的长度。由于它每跨一步都是整个数组,所以又称行数组。
int main()
{
int a = 10;
int *pa = &a;
double b = 99.9;
double *pb = &b;
char c = '@';
char *pc = &c;
printf("sizeof(int)= %u, sizeof(double)=%u, sizeof(char)=%u\n",
sizeof(int), sizeof(double), sizeof(char));
//最初的值
printf("&a=%p, &b=%p, &c=%p\n", &a, &b, &c);
printf("pa=%p, pb=%p, pc=%p\n", pa, pb, pc);
//加法运算
pa++; pb++; pc++;
printf("pa=%p, pb=%p, pc=%p\n", pa, pb, pc);
//减法运算
pa -= 2; pb -= 2; pc -= 2;
printf("pa=%p, pb=%p, pc=%p\n", pa, pb, pc);
return 0;
}
sizeof(int)= 4, sizeof(double)=8, sizeof(char)=1
&a=000000000061FE04, &b=000000000061FDF8, &c=000000000061FDF7
pa=000000000061FE04, pb=000000000061FDF8, pc=000000000061FDF7
pa=000000000061FE08, pb=000000000061FE00, pc=000000000061FDF8
pa=000000000061FE00, pb=000000000061FDF0, pc=000000000061FDF6
剩余12页未读,继续阅读
资源评论
孤蓬&听雨
- 粉丝: 6888
- 资源: 301
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 通道处理过程的模拟通常涉及对通道处理机制的理解与实现.txt
- Flume进阶-自定义拦截器jar包
- Dubins曲线算法讲解和在运动规划中的使用.pdf
- 上市公司-股票性质数据-工具变量(民企、国企、央企)2003-2022年.dta
- 上市公司-股票性质数据-工具变量(民企、国企、央企)2003-2022年.xlsx
- Reeds+Shepp曲线算法讲解和实现.pdf
- 毕业设计基于SpringBoot+MyBatisPlus+MySQL+Vue的外卖配送信息系统源代码+数据库
- 词向量(Word Embeddings)是自然语言处理(NLP)领域的一种重要技术.txt
- Surfer,线性函数
- MyBatis 的动态 SQL 是其核心特性之一.txt
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功