我是靠谱客的博主 成就黑米,这篇文章主要介绍黑马程序员——c语言学习---指针的探讨,现在分享给大家,希望可以做个参考。

-----------Java培训Android培训IOS培训.Net培训期待与您交流!------------ 
本节探讨c语言中最重要的指针,c语言之所以如此灵活,关键就在于指针的运用,这是一个难点,也是学c语言必须要掌握的内容。

1、什么是指针?

指针如其名字所示的一样,他是一种有方向性的数据,能够指向别的数据类型。首先要明白的一点是,指针也是一种数据。那么在c语言中的指针是怎么运作的呢?在c语言中,我们通过*来创建指针数据,我们通过一个例子来看:

复制代码
1
2
3
4
5
6
7
int a = 12; // 创建整形变量 a int *p = &a; // 创建指针 p 指向 a printf("a的地址:%p a的大小为:%lu Byte a的内容:%dn", &a, sizeof(a), a); // 输出 a 的地址、大小及存储内容 printf("p的地址:%p p的大小为:%lu Byte p的内容:%pn", &p, sizeof(p), p); // 输出 p 的地址、大小及存储内容 printf("p指向的内容为 %dn", *p); // 输出p指向的内容
在该例子中,我们创建了一个变量 a=12,然后创建了一个指针 p 指向 变量 a,我们看看程序输出情况:

复制代码
1
2
3
a的地址:0x7fff5fbff8d8 a的大小为:4 Byte a的内容:12 p的地址:0x7fff5fbff8d0 p的大小为:8 Byte p的内容:0x7fff5fbff8d8 p指向的内容为 12

从输出结果可以看出,变量 a 占用内存单元的4个字节,存储的是数值 12,指针 p 占用内存单元的8个字节,存储的是一个地址数据,进一步观察可以发现,p对应内存单元所存储的地址数据和变量a的地址一致,这样我们就可以通过 *p 直接访问 a 的内容,换句话说,*p 就是 a。验证如下:

复制代码
1
2
*p=13; printf("a = %dn", a); // 输出 a 的内容
前面的代码中我们给变量 a 赋值 12,在该代码中,我们没有直接对 a进行操作,我们看看结果又会怎样:

复制代码
1
a = 13
可以发现,我们通过指针 p 就可以间接修改 变量 a 的内容。


2、思考
通过上面的例子发现,我们可以通过指针绕过变量本身,直接修改变量的值,换句话说,我们可以通过指针直接操作变量对应的地址单元!这就是指针的本质。那么,为什么要这样做呢?

a、我们知道,数据在内存中的存储都是以基本的内存单元按顺序进行排列的,对变量的操作其本质就是操作变量对应的地址单元,我们每创建一个变量,实际上就是用一个标识符(变量名)标识了一块内存单元,这样当创建大量的变量时就会产生大量的标识符,这是不利于变量的调用的。当对大量的数据或者具有某种结构和顺序的数据进行操作时,指针的优势就凸现出来,因为指针是直接通过地址单元来操作变量的,而我们对地址单元的简单运算,就能在大量不同的变量之间跳转,非常的灵活。

b、当然这也产生了一些问题。由于指针是对地址单元的直接操作,而如果我们错误的将指针定位到不该指向的内容时,有时会导致整个程序的崩溃,这一点一定要注意。


3、特殊的指针

a、数组

c语言中数组本身就是一种指针,只不过写法略有不同。

复制代码
1
2
3
4
5
6
7
8
9
int ar[]={1,2,3}; int *arp=ar;//int *arp={1,2,3};这样是错误的 //输出数组的值 printf("%dn", arp[0]); // *arp printf("%dn", arp[1]); // *arp+1 printf("%dn", arp[2]); // *arp+2 printf("ar的地址: %pnarp的地址: %p n", &ar, &arp);

输出结果:

复制代码
1
2
3
4
5
1 2 3 ar的地址: 0x7fff5fbff8c8 arp的地址: 0x7fff5fbff8c0

在上面的例子中,我们将一个指针指向了数组,有没注意到数组名的前面没有加 &地址操作符?这是因为数组名本身就是一个指针!这两个指针占用不同的内存单元,但是他们都能对数组进行操作。

b、字符串

前面有提到,字符串本身就是一种数组,那同样的,他也可以用指针来表示:

复制代码
1
2
3
char *str = "This is a string!"; printf("%sn", str);
输出:

复制代码
1
This is a string!
c、指针数组

在数组名的前面加 * 就成为了指针数组:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
//创建指针常量数组 char *name[]= { "Jack", "Tom", "Helen", "April", }; // 输出 for (int i=0; i<4; i++){ printf(" %sn",name[i]); }
输出结果:

复制代码
1
2
3
4
Jack Tom Helen April
d、指针函数

函数本身也是一种指针(函数的细节将在别的章节讨论),我们当然也可以通过指针指向函数:

复制代码
1
2
3
4
5
6
7
8
9
10
//(*p)为固定写法,表示该指针指向函数 void (*p)(char); p=func; // 测试函数和指针指向的地址 printf("func地址: %pn", &func); printf("p指向地址: %pn", p); // 指针调用函数 (*p)('A'); // 可以简化为p('A')
输出结果:

复制代码
1
2
3
func地址: 0x100000e80 p指向地址: 0x100000e80 func()函数被调用,传入字符参数 A
可以发现这两个地址完全一致。


4、其他

在计算机领域流传一句话:多一层间接,没有解决不了的问题。指针是c语言构建简介结构的关键,在以c语言为基础的面向对象设计语言中,这种对指针的运用将显得格外突出和复杂。


-----------Java培训Android培训IOS培训.Net培训期待与您交流!------------ 

最后

以上就是成就黑米最近收集整理的关于黑马程序员——c语言学习---指针的探讨的全部内容,更多相关黑马程序员——c语言学习---指针内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(63)

评论列表共有 0 条评论

立即
投稿
返回
顶部