指针

作者: labi3285 | 来源:发表于2017-09-14 22:09 被阅读14次

本节探讨c语言中最重要的指针,c语言之所以如此灵活,关键就在于指针的运用,这是一个难点,也是学c语言必须要掌握的内容。

1、什么是指针?

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

int a = 12; // 创建整形变量 a  
int *p = &a; // 创建指针 p 指向 a  
printf("a的地址:%p  a的大小为:%lu Byte  a的内容:%d\n", &a, sizeof(a), a); // 输出 a 的地址、大小及存储内容  
printf("p的地址:%p  p的大小为:%lu Byte  p的内容:%p\n", &p, sizeof(p), p); // 输出 p 的地址、大小及存储内容  
printf("p指向的内容为 %d\n", *p); // 输出p指向的内容 

在该例子中,我们创建了一个变量 a=12,然后创建了一个指针 p 指向 变量 a,我们看看程序输出情况:

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。验证如下:

*p=13;  
printf("a = %d\n", a); // 输出 a 的内容 

前面的代码中我们给变量 a 赋值 12,在该代码中,我们没有直接对 a进行操作,我们看看结果又会怎样:

a = 13  

可以发现,我们通过指针 p 就可以间接修改 变量 a 的内容。

2、思考

通过上面的例子发现,我们可以通过指针绕过变量本身,直接修改变量的值,换句话说,我们可以通过指针直接操作变量对应的地址单元!这就是指针的本质。那么,为什么要这样做呢?
a、我们知道,数据在内存中的存储都是以基本的内存单元按顺序进行排列的,对变量的操作其本质就是操作变量对应的地址单元,我们每创建一个变量,实际上就是用一个标识符(变量名)标识了一块内存单元,这样当创建大量的变量时就会产生大量的标识符,这是不利于变量的调用的。当对大量的数据或者具有某种结构和顺序的数据进行操作时,指针的优势就凸现出来,因为指针是直接通过地址单元来操作变量的,而我们对地址单元的简单运算,就能在大量不同的变量之间跳转,非常的灵活。
b、当然这也产生了一些问题。由于指针是对地址单元的直接操作,而如果我们错误的将指针定位到不该指向的内容时,有时会导致整个程序的崩溃,这一点一定要注意。

3、特殊的指针

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

int ar[]={1,2,3};  
int *arp=ar;//int *arp={1,2,3};这样是错误的  
  
//输出数组的值  
printf("%d\n", arp[0]);   // *arp  
printf("%d\n", arp[1]);   // *arp+1  
printf("%d\n", arp[2]);   // *arp+2  
  
printf("ar的地址:  %p\narp的地址: %p \n", &ar, &arp);  

输出结果:

1  
2  
3  
ar的地址:  0x7fff5fbff8c8  
arp的地址: 0x7fff5fbff8c0 

在上面的例子中,我们将一个指针指向了数组,有没注意到数组名的前面没有加 &地址操作符?这是因为数组名本身就是一个指针!这两个指针占用不同的内存单元,但是他们都能对数组进行操作。
b、字符串
前面有提到,字符串本身就是一种数组,那同样的,他也可以用指针来表示:

char *str = "This is a string!";  
printf("%s\n", str); 

输出:

This is a string!  

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

//创建指针常量数组  
char *name[]=  {  
    "Jack",  
    "Tom",  
    "Helen",  
    "April",  
};  
// 输出  
for (int i=0; i<4; i++) {  
    printf(" %s\n",name[i]);  
} 

输出结果:

Jack  
Tom  
Helen  
April 

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

//(*p)为固定写法,表示该指针指向函数  
void (*p)(char);  
p=func;  
  
// 测试函数和指针指向的地址  
printf("func地址: %p\n", &func);  
printf("p指向地址: %p\n", p);  
  
// 指针调用函数  
(*p)('A'); // 可以简化为p('A')  

输出结果:

func地址: 0x100000e80  
p指向地址: 0x100000e80  
func()函数被调用,传入字符参数 A 

可以发现这两个地址完全一致。

4、其他

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

相关文章

  • 混淆知识点

    1、指针数组&数组指针、常量指针&指针常量、函数指针&指针函数 数组指针&指针数组 数组指针的定义 int (*p...

  • C语言

    C 指针、指针变量、函数指针、指针函数、指针数组、数组指针、C 数组

  • 指针

    普通指针指针的指针 数组指针 函数指针

  • 函数指针

    概念: 指针函数, 函数指针, 指针数组, 数组指针, 指向数组的指针, 指向函数指针数组的指针。

  • C:函数指针的坑

    关于该死的函数指针和指针函数 先来个目录 常量指针、指针常量 数组指针、指针数组 函数指针、指针函数 1、先看第一...

  • C 语言指针

    指针类型:指针的读取长度,指针的读取方向(大小端) 空指针,无类型指针,野指针 常量指针,指向常量的指针 http...

  • 二、C语言基础

    A、指针 指针的概念:指针变量 和 指针 的区别 ?答:指针变量是指针的标记,也可以通过指针变量的标记操作指针内存...

  • 王道程序员求职宝典(十一)指针与引用,树

    指针与引用 指针声明typedef别名类型检查void*指针指向指针的指针函数指针typedef简化函数指针定义初...

  • NDK02

    指针 指针概念 1 .指针变量和指针的区别?答: 指针变量是定义指针的标记,指针就是指向的内存地址。2 .函数指针...

  • 12 C指针

    1、指针定义 2、指针进阶 3、指针使用 4、多级指针 4、指针和数组 5、指针和字符串 6、高级指针之和指向函数的指针

网友评论

      本文标题:指针

      本文链接:https://www.haomeiwen.com/subject/zfsjsxtx.html