数组
1 - 指针对应的数组元素
int ages[5]={10,9,8,7,6}; int *p = ages;// 等同于:int *p = &ages[0]; // 第 1 个元素的地址 p,&ages[0] // 第 2 个元素的地址 p+1,&ages[1] // 第 3 个元素的地址 p+2,&ages[2] // ......
2 - 遍历数组元素(使用指针)
int ages[5]={101,19,21,33,22}; int *p = ages; for(int i=0;i<5;i++) printf("%d\t",*(p+i));
3 - 对于数组元素的 3 种访问形式
① 数组名[下标]
② 指针变量名[下标]
③ *(指针变量+下标)
char *arr[4]={"ios","iphone","ipod","abc"}; printf("%s \n",arr[1]); // 输出 iphone printf("%c \n",*(*(arr+1)+2));// 输出 h printf("%s \n",arr[2]); // 输出 ipod printf("%c \n",*(arr[2]+3)); // 输出 d
指针变量的 +1 或 -1 究竟是加、减多少?这取决于指针类型:如果是 char 类型的指针就加 1 个字节;如果是 int 类型的指针则加 4 个字节
4 - 用指针来接收一个数组,使指针变量指向数组首元素
void change(int array[]);// 等价于 void change(int *array)
5 - 数组名代表数组的首元地址,但需要注意的是它是一个指针常量。指针可以当数组名使⽤,区别是两者在内存中所占字节数不一样
char string[10] = "iphone"; char *p = string; printf("%p \n", p);// 输出地址 0x7fff5fbff62e *(p+1)='P';// 操作单个字符串 printf("%s\n",p); // 输出 iPhone printf("%c\n",*p);// 输出是 i printf("%c\n",*(p+2));// 输出 h p++;// 向高位偏移 printf("%s \n",p);// 输出 Phone printf("%c \n",*(p+1));// 输出 h printf("%s \n",string);// 输出 iPhone printf("%s \n",string+1);// 输出 Phone
指针 | 字符串
1 - 比较两行代码的不同
char name[] = "it"; char *name2 = "it"; name[0]='g'; printf("%s\n",name);// gt *name2= 'y';// crash printf("%s\n",name2);
说明:name 是字符串变量,而 *name2 是字符串常量。C语言 的数组元素存放于栈,里面的元素可以随便修改,称为字符串变量;而字符串常量存放于常量区,会缓存起来是不可更改的,以下简单验证
char *name1 = "it"; char *name2 = "it"; printf("%p\n%p\n",name1,name2);// 你会发现打印的地址是一样的,说明 name1 和 name2 指向的是同一个字符串
在控制台中经常使用数组来输入字符串,为什么 ?就是因为数组可变
char name[20]; printf("请输入姓名:\n"); scanf("%s",name); printf("您输入的姓名是:%s\n",name);
指针数组
1 - 指针数组就是在数组中存放的都是指针
// 3 行 20 列 char melee[3][20] = {"李小龙","查克·诺里斯","增根泰三"}; char *firstFighter[3] = {"fist","foot","waist"}; // 等价于 char firstFighter[3][20] firstFighter[0] = &melee[1][0];// 重新指向 printf("%s\n",*firstFighter); // 查克·诺里斯