指针数组
(一个数组,里面全是指针)
int *p[n]; [ ]优先级高,先与p结合成为一个数组,再由int*说明这是一个整型指针数组,它有n个指针类型的数组元素。
指针数组就是数组,数组里每个元素都是指针,int *p[5]这个一维数组里面有五个指针变量,p[0]、p[1]、...、p[4]。
下标 | 0 | 1 | 2 | 3 | 4 |
元素 | int* | int* | int* | int* | int* |
指针数组用法一(不推荐):
#include<stdio.h>
#include<stdlib.h>
int main()
{
int a=1,b=2,c=3,d=4,e=5;
int *p[5]={&a,&b,&c,&d,&e};
int i;
for(i=0;i<5;i++)
{
printf("%d\n",*p[i]);
}
system("pause");
return 0;
}
指针数组的常用思路———用来取代二维数组:
#include<stdio.h>
#include<stdlib.h>
int main()
{
char *p1[5]={"22222","dhfakhg","dddfae","eeee","cccc"};
//里面每个指针都指示一个数组的开头
int i;
for(i=0;i<5;i++)
{
printf("%s\n",p1[i]);
//这里不能加*号,加了*号取出来的是第一个字符,而我们要的是字符的地址,取出那个字符串
}
system("pause");
return 0;
}
1、char a[10]="hello";(√)初始化
2、char a[10]; a="hello";(x)因为数组名是一个常量,不能作左值。
3、char *p="hello";(√)
4、char *p; p="hello";(√)
5、char a[ ]="hello";char *p=&a; (x)
6、char a[ ]="hello";char *p=a; (√)
7、char *p[5]={"eee","dygydggdy","vvvv","999221","aaaa"};(√)
数组指针
(一个指针,指向数组)
int(*p2)[n] (n为要定义的个数)
()里是*p2,先定义了指针,然后才是[ ],才是数组,即数组指针。它指向了n个含有int 类型的数组。
//#include <stdio.h>
//#include <stdlib.h>
//#include <string.h>
//int main()
//{
// int temp[5]={1,2,3,4,5};
// int *p=temp; /*指针指向数组第一个元素(整型变量)的地址,
而不是指向数组;而数组指针才是指向数组的地址*/
// int i;
// for(i=0;i<5;i++)
// {
// printf("%d\n",*(p+i));
// }
// system("pause");
// return 0;
//}
//#include <stdio.h>
//#include <stdlib.h>
//#include <string.h>
//int main()
//{ //典型错误
// int (*p2)[5]={1,2,3,4,5}; //p2是指针,所以给它的应该是一个地址才行。
// int i;
// for(i=0;i<5;i++)
// {
// printf("%d\n",*(p2+i));
// }
// system("pause");
// return 0;
//}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int temp[5]={1,2,3,4,5};
int (*p2)[5]=&temp; /*temp表示数组第一个元素的地址,
又因为(*p2)[5]是指向数组的指针,所以等于&temp*/
int i; /*(*p2)[5]占的是5个int字节,
如果只用一个temp一个首地址显然不对。*/
for(i=0;i<5;i++)
{
printf("%d\n",*(*p2+i)); /*p2=&temp 数组的地址,
*p2=temp 数组第一个元素的地址*/
}
system("pause");
return 0;
}
注意:p2在内存中指向的是这个数组的首地址,是和数组有关联的,而不仅仅是指向数组首元素的地址(指向数组和指向数组首元素地址不同)。
int a[5]={1,2,3,4,5}; int *p2=a;
//p2指向的是a数组首元素的地址,而不是指向这个数组,它与整个数组是无关的。
int(*p)[5]={1,2,3,4,5} ; 错误写法
int a[5]={1,2,3,4,5}; int(*p)[5]=&a; 正确写法
题外话:已知数组a[5], a 和 &a[0]是数组首元素地址;&a是数组的首地址。我们习惯上把数组首元素地址作为该数组的地址。
重点强调:array是数组第一个元素的地址,所以array+1指向数组第二个元素;&array是整个数组的地址,所以&array+1指向整个数组最后的位置(第二个array数组的起始位置)。
指针±整数
若指针类型为int*的指针+1,那么他将跳过4个字节的大小指向4个字节以后的内容。若指针类型为char*的指针+1,那么他将跳过1个字节的大小指向下一个字节以后的内容。指针的类型决定了指针向前或者向后走一步有多大的距离。
解引用
指针pa中存储的是a变量的内存地址,通过地址去获得a的值的操作就叫做解引用,在c语言中通过运算符*就可以拿到一个指针所指地址的内容了。比如*pa就能获得a的值。pa指针首先是一个变量,它本身也占据一块内存,这块内存存放的就是a变量的首地址。当解引用的时候,就会从这个首地址连续划出 4 个 byte,然后按照 int类型的编码方式解释。指针的类型决定了指针解引用的时候能够访问几个字节的内容。若指针类型为int *,那么将它进行解引用操作,它将可以访问从指向位置开始向后4个字节的内容,以此类推。
指针的类型决定了,对指针的解引用时有多大的权限(能操作几个字节),如char*的指针解引用就只能访问一个字节,而int*的指针解引用能访问四个字节。