1.指针是个变量,用来存放地址,内存会划分为小的内存单元,每个内存单元都有一个编号,这个编号就被成为地址,把地址也叫指针。
内存编号=地址=指针
指针或地址要储存就可以存放到指针变量中
2.指针的大小32位平台4字节64位平台8字节
3.指针有类型,指针的类型决定了指针+-整数的步长,指针解引用操作时候的权限
4.指针的运算:
指针+-整数
指针-指针
指针的关系运算
一、字符指针
int main()
{
char ch='w';
char *pc=&ch;
*pc='a';
printf("%c\n",ch);//a
const char*p="abcdef";//把字符串首字符a的地址存入,加const保护
//*p='w';//err
//p是指针变量,在x86环境下是4个字节
printf("%c\n",*p);//a
printf("%s\n",p);//abcdef
}
int arr[10]={1,2,3,4,5,6,7,8,9,10}
int*p=arr;//p指向第一个元素
int main()
{
const char*p1="abcdef";
const char*p1="abcdef";
char arr1[]="abcdef";
char arr2[]="abcdef"
if(p1=p2)
{
printf("p1==p2\n");
}
else
{
printf("p1!=p2\n");
}
if(arr1==arr2)
{
printf("arr1==arr2\n");
}
else
{
printf("p1!=p2\n");
}
}
常量字符串内容一模一样不能修改的只存放一份所以p1=p2
创建了arr1和arr2放的内容一样,两个数组都存在,arr1和arr2首元素地址不相同arr1不等于arr2
二、指针数组
指针数组:存放指针的数组
int *arr[10];//存放整型指针的数组
char*ch[5];//存放字符指针的数组
int a=10,b=20,c=30;
int *arr[3]={&a,&b,&c};//arr就是一个指针数组
for(int i=0;i<3;i++)
{
printf("%d ",*(arr[i]));//10 20 30
}
int main()
{
int arr1[5]={1,2,3,4,5};
int arr2[5]={2,3,4,5,6};
int arr3[5]={3,4,5,6,7};
int *parr[3]={arr1,arr2,arr3};
for(int i=0;i<3;i++)
{
for(int j=0;j<5;j++)
{
printf("%d ",parr[i][j]);//或*(parr[i]+j)
}
printf("\n");
}
}
三、数组指针
1.数组指针:是指针,指向数组的地址
int *p1[10];//p1是数组,存放指针的数组
int(*p2)[10] ;//p2是指针,指向数组的指针,数组中的元素是int
int main()
{
int a=10;
int *pa=&a;
int arr[10]={0};//数组名是首元素地址
int (*p)[10]=&arr//p是指针指向数组所以p叫数组指针,去掉变量名p剩下的是类型
}
char*arr[5];
//p=&arr;
//p的类型:char*(*p)=&arr
2.数组名
通常情况下,我们说的数组名都是数组首元素的地址,但有2个例外:
1)sizeof(数组名),这里的数组名表示整个数组,sizeof(数组名)计算的是整个数组的大小
2)&数组名,这里的数组名表示整个数组,&数组名,取出的是整个数组的地址
3.数组指针有什么用
void print1(int arr[],int sz)
{
for(int i=0;i<sz;i++)
{
printf("%d ",arr[i]);
}
printf("\n");
}
//形参写成指针形式
void print1(int* arr,int sz)
{
for(int i=0;i<sz;i++)
{
printf("%d ",*(arr+i));
}
printf("\n");
}
void print2(int(*p)[10],int sz)//这不是推荐的写法
{
for(int i=0;i<sz;i++)
{
//*p给数组的地址&arr解引用得到数组名arr,数组名是首元素地址
printf("%d ",*(*p+i));
}
}
int main()
{
int arr[10]={1,2,3,4,5,6,7,8,9,10};
//写一个打印arr数组的函数
int sz=sizeof(arr)/sizeof(arr[0]);
print1(arr1,sz);
print2(&arr,sz);
}
void print1(int arr[3][5],int c,int r)
{
for(int i=0;i<c;i++)
{
for(int j=0;j<r;j++)
{
printf("%d ",arr[i][j]);
}
printf("\n");
}
}
void print2(int (*p)[5],int c,int r)
{
for(int i=0;i<c;i++)
{
for(int j=0;j<r;j++)
{
//p+i指向第i行是第i行的地址
//*(p+i)对第i行地址解引用得到第i行数组名就是第i行首元素地址
printf("%d ",*(*(p+i)+j))//或p[i][j];
}
printf("\n");
}
}
int main()
{
int arr[3][5]={{1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7}};
//写一个函数打印arr数组
print1(arr,3,5);