目录
取地址运算:&运算符取得变量的地址
运算符&:·scanf("%d",&i);里的&。
可以获得变量的地址,它的操作对象必须是变量。
例:int i; printf("%x",&i);
·地址的大小是否与int相同取决于编译器。
如图可见64位架构的编译器中地址的大小与int不相等
·若要printf输出一个地址则需使用"%p"
&不能取的地址:·&不能对没有地址的的东西取地址
例:&(a+b) X
&(a++) X
&(++a) X
指针:
·指针:·就是用来保存地址的变量。
例:int i; *:表示一个变量为指针变量
int *p=&i;
int* p,q;
int *p,q; //后两行均表示p为一个指针,q为一个int类型的变量
·若*p保存了变量i的地址,则可说“p指向i”
·指针变量:·变量的值是内存的地址
·普通变量的值是实际的值
·指针变量的值是具有实际值变量的地址
·作为参数的指针:·void f(int *p);
·在被调用的时候得到了某个变量的地址:
·int i=0; f(&i);
·在函数里面可以通过这个指针来访问外面的这个i
·*:访问那个地址的变量:
·*是一个单目运算符,用来访问指针的值所表示的地址上的那 个变量
·可以做右值也可以做左值
·指针的运算符& *:
·互相反作用:
例:*&yptr —> *(&yptr)—>*(yptr的地址)—>得到那个地址上的变量—>yptr
指针的使用:
·应用一:·交换两个变量的值
void swap(int *pa,int *pb){
int t=*pa;
*pa=*pb;
*pb=t;
·应用二:
·函数返回多个值,某些值就只能通过指针返回
·传入的参数实际上是需要保存带回的结果的变量
·应用二b:
·函数返回运算的状态,结果通过指针返回
·常用的套路是:让函数返回特殊的不属于有效范围内的值来表示出错:
例:-1 / 0
·但是当任何数值都是有效的可能结果是就得分开返回了
·指针最常见的错误:
·定义了指针变量,还没有指向任何变量,就开始使用指针
(任何一个地址变量没有得到一个实际变量的地址之前,不能用*去访问任何数据,否则是没有意义的)
指针与数组:
·传入函数的数组成了什么?
·函数参数表中的数组实际上是指针
·sizeof(a)==sizeof(int*)
·但是可以用数组的运算符[]进行计算
·数组参数:·以下四种函数原型是等价的:
·数组变量是特殊的指针:
·数组变量本身表达地址,所以
·int a[10] ; int *p=a; //无需用&取地址
·但是数组的单元表达的是变量,需要用&取地址
·a==&a[0]
·运算符可以对数组做,也可以对指针做:
·p[0] <==> a[0]
·*可以对指针做,也可以对数组做: ·*a=25
·数组变量是特殊const的指针,所以不能被赋值:
·int a[] <==> int *const a=...
指针与const:
·指针是const:
·表示一旦得到某个变量的地址,不能再指向其他变量
·int *const q = &i; //q是const
·*q = 26; //OK
·q++; //ERROR!
·所指是const:
·表示不能通过这个指针去修改那个变量(并不能使得那个变量成为const)
·const int *p=&i;
·*p = 26; //ERROR!
· i = 26; //OK
· p = &j; //OK
·注意区分以下的几段代码:
判断哪个被const了的标志是const在*的前面还是后面:
const在*前:它所指的东西不能修改
const在*后:指针不能被修改
·转换:·总是可以吧一个非const的值转换成const
·当要传递的参数类型比地址大的时候,这是常用手段!
既能用较少的字节传递值给参数,
又能避免函数对外面的变量的修改
·const 数组:
·const int a[]={1,2,3,4,5,6}
·数组变量已经是const指针了,这里的const表示数组的每个单元都是const int (所以必须通过初始化赋值,否则数组内无单元)
·保护数组值:
·因为把数组传入函数时传递的是地址,所以那个函数内部可以修改数组的值
·为了保护数组不被函数破坏,可以设置参数为const
·int sum(const int a[], int length);
指针运算:
·指针运算:
·给一个指针+1表示要让指针指向下一个变量
例:int a[];
int *p = a[0];
*(p+1) —> a[1];
·如果指针不是指向一片连续的分配的空间,如数组,则这种运算是没有意义的
·*(p+n) <==> a[n]
·以下的算数运算可以对指针做:
·给指针加、减一个整数(+,+=,-,-=)
·递增递减(++/--)
·两个指针相减(结果为 地址差/sizeof[类型])
·指针比较:
·<,<=,==,>,>=,!=都可以对指针做
·指针的类型:
·无论指针指向什么类型,所有的指针大小都是一样的,因为都是地址
·指向不同类型的指针是不能直接互相赋值的
·指针的类型转换:
·void*:不知道指向什么东西的指针
·计算时与char*相同(但不相通)
·指针转换类型:
例:int *p = &i; void *q = (void*)p;
·这并没有改变p所指的类型,而是让后人用不同的眼光通过p看它的变量。
·指针用来做什么:
·需要传入较大的数据时用作参数
·传入数组后对数组做操作
·函数返回不止一个结果
·需要用函数来修改不止一个变量
·动态申请内存