本人在学C语言时,发觉指针很难搞,于是作了几点总结
一.概念区分:
1) 指针和指针变量:
指针:一个变量的地址称为该变量的指针。
指针变量:一个变量专门存放另一个变量的地址。(地址是以八进制数保存的 %o)
2)*p++与*(p++):二者相同,先得到p指向变量的值,后再加加。
(*p)++与*p++:前者相当于(a[0])++,即a++。后者同上。
*(p++)与*(++p):后者是先使指针加一,然后再取值。
3) ++*p与(*p)++:前者是++a,后者是a++
++*p与*p++:
(*p)++与*p++
4)实参数组名与形参数组名:
数组名做实参时,代表一个固定的地址(指针常量),但形参数组并不是一个固定的地址值(指针变量)。
5)[ ]是变址运算符:将a[i]先按a+i计算地址,然后找出地址单元的值。
6) int *p;int *p[ ]; int (*p)[ ]; int *p( ); int (*p)( ); int **p的概念区分:
①
int (*p)():指向函数的指针
eg: int max(int, int);
int (*p)(int,int);
p=max; /*将函数
max的入口地址赋给指针变量p,函数名代表该函数的
c=(*p)(a,b); 入口地址
*/
应用:把指针作为参数传递到其他函数,这样就能够在被调用的函数中使用实参函数。
二.数组与指针
1)一维数组与指针:
p=a;&a[0]
数组元素地址:
1.p+i = a+i
2.&p[i]=&a[i]
数组元素引用:
1.*(p+i)=*(a+i)
2.p[i]=a[i]
2)二维数组与指针:
定义:
int a[3][4]={{1,2,3,4},{9,11,13,15},{17,19,21,23}}
a是一个数组名。a数组包括3行,即3个元素:a[0],a[1],a[2].而每一个元素又是一个一维数组。因此a代表的是首行首地址。由于a[0],a[1],a[2]又是一维数组名,C语言规定
数组名代表数组首元素地址。—— a[0]代表一维数组a[0]中第0列元素的地址,即&a[0][0].
表示形式
|
含义
|
a ,&a[0]
|
二维数组名,指向一维数组a[0],即0行首地址
|
a[0],*(a+0),*a,&a[0][0]
|
0行0列首地址
|
a+1,&a[1]
|
1行首地址
|
a[1],*(a+1),&a[1][0]
|
1行0列元素的地址
|
a[1]+2,*(a+1)+2,&a[1][2]
|
1行2列元素的地址
|
*(a[1]+2),*(*(a+1)+2),a[1][2],(*(a+1))[2]
|
1行2列元素
|
**(a+1)
|
1行元素
|
a+i ,&a[i]
|
i行地址
|
a[i], *(a+i)
|
i行0列地址
|
a[i]+j, *(a+i)+j
|
i行j列地址
|
指针赋值:
①p指向数组元素:
int *p;
p=&a[0][0];
p=a[0];
p=*a;
p=*(a+0);
② p是行指针:
int (*p) [n];
p=a;
p=&a[0];
数组地址表示法:
数组元素表示法:
三.经典概念程序题:
a)
指针做函数参数:
swap()
1)
#include <stdio.h>
void swap(int *x, int *y)
结果:5,3
{
int t;
t = *x;
*x = *y;
//指针所指向的变量的内容发生交换
*y = t;
}
void main ()
{
int a=3,b=5;
swap(&a, &b);
printf(“%d,%d”,a,b);
}
2)
#include <stdio.h>
void swap(int *x, int *y)
结果:3,5
{
int *t;
t = x;
x = y;
//地址值进行交换,由于地址也是形参,所以返回
y = t;
//主函数时,空间被释放,而没有交换a,b值。
}
void main ()
{
int a=3,b=5;
swap(&a, &b);
printf(“%d,%d”,a,b);
}