首页 > 技术文章 > C语言 - 指针 1.2:指数组 | 指针数组

self-epoch 2019-06-13 17:54 原文

数组

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);  // 查克·诺里斯

 

推荐阅读