指针的概念:
int *ptr; 指针,int *型 -> int
char *ptr; 指向char型的指针,char *型 -> char
int **ptr; 指向指针的指针,int **型 -> int *
int *ptr[3]; 指向数组的指针,int(*)[3]型 -> int()[3]
int *(*ptr)[4]; 指向指针的指针数组,int *(*)[4]型 -> int *()[4]
指针的算术运算:
(*ptr)++; 指针的内容++ ptr[*ptr]
ptr++; 指针的地址++ *ptr='A',ptr=0x1234
运算符&和*:
int a=1,b;
int *p,**ptr;
p=&a;
*p=1; 指针p中的内容赋值1
ptr=&p; 双指针 <- 指针的地址
*ptr=&b *ptr是单指针
**ptr=1; 双指针的内容的内容是1
指针表达式;
char *arr[20]; 指向数组的指针
char **parr=arr; arr看作指针,arr也是指针表达式
char *str;
str=*parr; *parr是指针表达式
str=*(parr+1); *(parr+1)是指针表达式
数组和指针的关系: 复杂一些
int array[10]={0,1,2,3,4,5,6,7,8,9},value;
value=array[0]; value=*array;
value=array[3]; value=*(array+3);
value=array[4]; value=*(array+4);
一个数组TYPE array[n]有两重含义: 第一,它代表整个数组, 第二,它是一个指针,建立在单独的内存区中.
char *str[3]={"Hello,this is a sample!", "Hi,good morning.", "Hello world"};
第一,str是一个三单元的数组,该数组的每个单元都是一个指针
第二,它是一个指针,它的类型是char**
char s[80];
strcpy(s,str[0]); strcpy(s,*str);
strcpy(s,str[1]); strcpy(s,*(str+1));
strcpy(s,str[2]); strcpy(s,*(str+2));
指针和结构类型的关系:
struct MyStruct{int a;int b;int c;}
MyStruct ss={20,30,40};
MyStruct *ptr=&ss;
ptr->a; ptr->b; ptr->c;
int *pstr=(int*)&ss;
*pstr; *(pstr+1); *(pstr+2);
不正规,因为存储区里双字对齐会填充字节,说不定*(pstr+1)就正好访问到了这些填充字节.
int *pstr=ss;
*pstr; *(pstr+1); *(pstr+2); 这是对的,数组可以.
指针和函数的关系: ?
int fun1(char*,int);
int (*pfun1)(char*,int);
pfun1=fun1;
int a=(*pfun1)("abcdefg",7); 通过指向函数的指针来调用函数。
可以把指针作为函数的形参。在函数调用语句中,可以用指针表达式来作为实参。
int (*p)(); 函数指针,指向函数的指针p,有两个用途:调用函数和做函数的参数.
int *p(); 指针函数,返回值是一个指针。
int func(int i)
{}
void main()
{
int (*p)(int);
p = func;
..(*p)(n)..;调用函数
}
指针类型转换:
void fun(char*);
int a=125,b;
fun((char*)&a);
...
void fun(char*s) 把一个整数的四个字节的顺序来个颠倒。
{
char c;
c=*(s+3);*(s+3)=*(s+0);*(s+0)=c;
c=*(s+2);*(s+2)=*(s+1);*(s+1)=c;
}
指针的安全问题:
char s='a';
int *ptr;
ptr=(int*)&s;
*ptr=1298; 修改了4个字节的内容.
程序员心里必须非常清楚:指针究竟指到了哪里.