1.scanf
我们思考一下以下问题:
后面是老师的经典名言,要求全文背诵:学计算机一定要有一个非常强大的心理状态,什么呢,计算机的所有东西都是人做出来的,别人能想得出来的,我也一定能想得出来,在计算机里头没有任何黑魔法,所有的东西只不过是我现在不知道而已,总有一天我会把所有的细节所有的内容,内部的东西全都搞明白了,那个scanf里面到底怎么做事情的,只不过我们现在才刚开始学习,我们还没有来得及去看,scanf的原始的代码是怎么样的,scanf也不过是个函数,也不过是某个人给他写出来的,那个人和我们一样,同样只是一个脑袋而已.(泪目)
我们知道,如果你把一个地址交给整数,那么这件事是不靠谱的,因为整数和地址不见得永远都是系统的类型,那么什么样类型可以接收取地址得到的那个地址呢?指针.
2.指针
一个指针变量,就是保存地址的变量.以下是对指针的一些定义:
第一第二个语句的意思是,我们定义了一个变量i,然后定义了一个指针p指向变量i,*表明这个变量是指针类型.如图:
然后第三第四句我们要小心,这两句话的意思是一样的,都是定义了一个指向int的指针p和一个整型变量q.
指针变量
3.作为参数的指针
试一下这段代码:
运行结果:
我们可以看到,在main里面i的地址是70,我们把这个地址取出来传给f函数,这个地址也是70.
如果我们已经有了一个地址,我们想访问这个地址上的变量,这时候我们可以用*运算符.
我们可以来试一下这件事情:
运行结果:
由此我们可以知道,通过p这个指针,我们访问到了p所指的那个int i里面的值,我们进一步,接下来还要做更加邪恶的事情.我们在f函数的最后加这么一个语句:*p=26;我们会发现输出的k变成了26,这意味着经过f函数的调用后i的值被改了.我们在讲函数的时候一再再说c语言的函数调用的时候,发生的参数的转移,那是一种值的传递.所以在函数里面,函数的参数和调用它的地方没有任何的联系.现在情况有点不一样.我们把地址值传进去,这仍然是一种值的传递.但是因为传进来的是地址,所以通过这个值在函数内部我们可以以这种方式去访问到外面的这个i变量.
4.一些问题
*左值为什么叫左值?
*指针的两个运算符& *
传入地址
因为在32位架构下地址和int是一样大的,如果你传了一个int给它,它会认为这是一个地址,然后往里面写入东西,虽然它编译会给你通过(warning),但是运行一定会出错.运行一定会出错,是因为scanf把它读进来的那个数字写到了不该写的地方,它没有写到你的i里头去,如i=6,6那个地方很小,是不能写的,那个地方有很重要的东西.