9.1-1 取地址运算
运算符 &
• scanf(“%d”, &i);⾥的&
• 获得变量的地址,它的操作数必须是变量
• int i; printf(“%x”,&i);
• 地址的⼤⼩是否与int相同取决于编译器
• int i; printf(“%p”,&i);
&不能取的地址
• &不能对没有地址的东⻄取地址
• &(a+b)?
• &(a++)?
• &(++a)?
试试这些&
• 变量的地址
• 相邻的变量的地址
• &的结果的sizeof
• 数组的地址
• 数组单元的地址
• 相邻的数组单元的地址
9.1-2 指针
scanf
• 如果能够将取得的变量的地址传递给⼀个函数,
能否通过这个地址在那个函数内访问这个变量?
• scanf(“%d”, &i);
• scanf()的原型应该是怎样的?我们需要⼀个参数
能保存别的变量的地址,如何表达能够保存地址
的变量?
指针
• 就是保存地址的变量
int i;
int* p = &i;
int* p,q;
int *p,q;
指针变量
count
• 变量的值是内存的地址
7
• 普通变量的值是实际的值
countPtr count
• 指针变量的值是具有实际值的变量的地址
7
作为参数的指针
• void f(int *p);
• 在被调⽤的时候得到了某个变量的地址:
• int i=0; f(&i);
• 在函数⾥⾯可以通过这个指针访问外⾯的这个i
访问那个地址上的变量*
• *是⼀个单⺫运算符,⽤来访问指针的值所表⽰的地
址上的变量
• 可以做右值也可以做左值
• int k = *p;
• *p = k+1;
*左值之所以叫左值
• 是因为出现在赋值号左边的不是变量,⽽是值,是表
达式计算的结果:
• a[0] = 2;
• *p = 3;
• 是特殊的值,所以叫做左值
指针的运算符&*
• 互相反作⽤
• *&yptr -> * (&yptr) -> * (yptr的地
址)-> 得到那个地址上的变量 -> yptr
• &*yptr -> &(*yptr) -> &(y) -> 得到y的地
址,也就是yptr -> yptr
传⼊地址
• 为什么
• int i; scanf(“%d”, i);
• 编译没有报错?
指针应⽤场景⼀
• 交换两个变量的值
指针应⽤场景⼆
• 函数返回多个值,某些值就只能通过指针返回
• 传⼊的参数实际上是需要保存带回的结果的变量
指针应⽤场景⼆b
• 函数返回运算的状态,结果通过指针返回
• 常⽤的套路是让函数返回特殊的不属于有效范围内的
值来表⽰出错:
• -1或0 (在⽂件操作会看到⼤量的例⼦)
• 但是当任何数值都是有效的可能结果时,就得分开返
回了
• 后续的语⾔(C++,Java)