经常容易混淆的指针概念
第一组:
1、 int *a[10];
这是个指针数组,数组 a 中有 10 个整型的指针变量
a[0]~a[9] ,每个元素都是 int *类型的指针变量
2、int (*a)[10];
数组指针变量,它是个指针变量。它占 4 个字节,存地址编号。
它指向一个数组,它加 1 的话,指向下个数组。
3、 int **p;
这个是个指针的指针,保存指针变量的地址。
它经常用在保存指针的地址:
常见用法 1:
int **p
int *q;
p=&q;
常见用法 2:
int **;
int *q[10];
分析:q 是指针数组的名字,是指针数组的首地址,是 q[0]的地址。
q[0]是个 int *类型的指针。 所以 q[0]指针变量的地址,是 int **类型的。
p=&q[0]; 等价于 p=q
例 34: void fun(char**p) { int i; for(i=0;i<3;i++) { printf("%s\n",p[i]);//*(p+i) } } int main() { char *q[3]={"hello","world","China"}; fun(q); return 0; }
第二组:
1、int *f(void);
注意:*f 没有用括号括起来
它是个函数的声明,声明的这个函数返回值为 int *类型的。
2、int (*f)(void);
注意*f 用括号括起来了,*修饰 f 说明,f 是个指针变量。
是个函数指针变量,存放函数的地址,它指向的函数, 必须有一个 int 型的返回值,没有参数。
特殊指针
1、空类型的指针(void *)
char * 类型的指针变量,只能保存 char 型的数据的地址
int * 类型的指针变量,只能保存 int 型的数据的地址
float* 类型的指针变量,只能保存 float 型的数据的地址
void * 难道是指向 void 型的数据吗? 不是,因为没有 void 类型的变量
void* 通用指针,任何类型的地址都可以给 void*类型的指针变量赋值。
int *p;
void *q;
q=p 是可以的,不用强制类型转换
举例: 有个函数叫 memset
void * memset(void *s,int c,size_t n);
这个函数的功能是将 s 指向的内存前 n 个字节,全部赋值为 c。
memset 可以设置字符数组、整型数组、浮点型数组的内容,所以第一个参数,就必须是个通用指针。
它的返回值是 s 指向的内存的首地址,可能是不同类型的地址。所以返回值也得是通用指针
注意:void*类型的指针变量,也是个指针变量,在 32 为系统下,占 4 个字节
2、NULL
空指针:
char *p=NULL;
咱们可以认为 p 哪里都不指向,也可以认为 p 指向内存编号为 0 的存储单位。
在 p 的四个字节中,存放的是 0x00 00 00 00
一般 NULL 用在给指针变量初始化。
main 函数传参
例 35: #include <stdio.h> int main(int argc, char *argv[]) { int i; printf("argc=%d\n",argc); for(i=0;i<argc;i++) { printf("argv[%d]=%s\n",i,argv[i]); } return 0; }