在 C 语言中用的最多的就是指针了,指针一样也是 C 语言的精华所在了。咱们今天就来看看指针究竟是什么,它是如何使用的。面试
咱们先来回想下变量,在程序中的变量只是一段存储空间的别名,那么是否是必需要经过这个别名才能使用这段存储空间呢?答案确定不是的,咱们还能够经过指针来使用这段存储空间。在指针声明时,* 号表示所声明的变量为指针。在指针使用时,* 号表示取指针所指向的内存空间中的值。咱们经过下面这幅图能够更加直观的看出他们的关系ide
经过这个图片咱们是否是更加直观的看出它们的关系呢。上面即表示的是变量 p 保存着变量 i 的内存地址,即 p <--> &i; *p <--> i。函数
下来咱们经过示例代码进行分析说明,代码以下学习
#include <stdio.h> int main() { int i = 0; int* pI; char* pC; float* pF; pI = &i; *pI = 10; printf("%p, %p, %d\n", pI, &i, i); printf("%d, %d, %p\n", sizeof(int*), sizeof(pI), &pI); printf("%d, %d, %p\n", sizeof(char*), sizeof(pC), &pC); printf("%d, %d, %p\n", sizeof(float*), sizeof(pF), &pF); return 0; }
咱们在678行分别定义了 int* char* float* 类型的指针,在第10行经过指针 pI 指向了 i 的地址,再经过第12行的取指针的内容并赋值来达到改变 i 的值。那么咱们接下来打印下指针 pI 的地址,i 的地址还有 i 的值分别是什么。还有看下三种不一样类型的指针所占的内存大小和地址各是什么,编译结果以下spa
那么咱们看到指针 pI 和 i 的地址相同,而且 i 的值已经经过指针成功改变为10。接着咱们看到不论是什么类型的指针所占的内存大小都是4,并非咱们以前所认为的 int 为4,char 为1,float 为4啦,它们的地址连续着。说明指针在内存中并无类型之分,所存储的内存都是在同一个段上。指针
咱们接下来再来看个传值调用和传址调用。那么在程序中,指针也是变量,所以能够声明指针参数。当一个函数体内部须要改变实参的值,则须要使用指针参数。函数调用时实参值将复制到形参,指针适用于复杂数据类型做为参数的函数中。咱们下来利用示例代码进行说明传值调用和传址调用的区别,代码以下blog
#include <stdio.h> int swap(int a, int b) { int c = a; a = b; b = c; } int main() { int aa = 1; int bb = 2; printf("aa = %d, bb = %d\n", aa, bb); swap(aa, bb); printf("aa = %d, bb = %d\n", aa, bb); return 0; }
咱们想固然是 swap 函数能完成两个数交换的功能,咱们来编译下,看看是否能交换呢?图片
结果是这样的,卧槽,是咱们搞错了嘛。看来看去以为程序就该这么写啊,咱们再来仔细分析下。咱们在第19行只是将变量 aa 和 bb 的值复制给了 swap 函数的实参 a 和 b。在 swap 函数内部确实完成 a 和 b 的值交换,但只是 a 和 b 的值交换了而已。换句话说,这时他两跟变量 aa 和 bb 没啥关系,咱们这种就属于传值调用。咱们再将 swap 函数改为下面这样呢?看看结果如何内存
int swap(int* a, int* b) { int c = *a; *a = *b; *b = c; }
再将 main 函数中第19行改为 swap(&aa, &bb); 咱们来看看编译结果如何it
咱们看到加了个 * 号,居然神奇般改变了 aa 和 bb 的值。感受很神奇啊,咱们仔细分析下,这就是属于利用指针指向变量 aa 和 bb 的地址,而后再经过 * 取地址处的内容再赋值改变。这样就是咱们所说的传址调用啦。
咱们下来再来看看一个笔试面试中常常会问到的问题:a> const int* p;b> int const* p;c> int* const p;d> const int* const p 四种有什么区别。咱们来一一分析:a> p 可变但它指向的内容不可变;b> p 可变但它指向的内容不可变;c> p 不可变但它所指向的内容是可变的;d> p 和它所指向的内容都是不可变的。咱们对待这种问题有个口诀就是:左数右指(这是唐长老总结出来的)。什么意思呢?就是当 const 出如今 * 号左边时指针指向的数据为常量,当 const 出如今 * 号右边时指针自己为常量。这样是否是就很好记了呢?反正博主是记住了哈。
咱们下来再来个示例代码对其进行说明,代码以下
#include <stdio.h> int main() { int i = 0; const int* p1 = &i; int const* p2 = &i; int* const p3 = &i; const int* const p4 = &i; *p1 = 1; // compile error p1 = NULL; // ok *p2 = 2; // compile error p2 = NULL; // ok *p3 = 3; // ok p3 = NULL; // compile error *p4 = 4; // compile error p4 = NULL; // compile error return 0; }
咱们看到第12行明显会出错,由于 const 出如今 * 号的左边,左数右指嘛,就是它所指向的内容是不可变的。第15行也是一样的错误。第19行则是由于 p3 是 const 出如今 * 号的右边,因此它自己不可变。p4 先后都有 const,因此第2一、22行均会出错。咱们来看看分析是否正确呢
咱们看到结果与咱们分析的是一致的,咱们之后遇到这种笔试面试题岂不是送分题啦?哈哈,开个玩笑了,其实仍是很简单的只需记住口诀就好。咱们看看指针是不是那样传说中的难呢?其实也不难的。经过对指针的学习,咱们总结以下:一、指针是 C 语言中一种特别的变量;二、指针所保存的值是内存的地址;三、能够经过指针修改内存中的任意地址内容。
欢迎你们一块儿来学习 C 语言,能够加我QQ:243343083。