编译器:Microsoft Visual Studio 2010
前言
字符指针: char*
int main()
{
char* p ="abcdef";//"abcdef"是一个常量字符串,指针内存放的是首元素的地址。
printf("%c\n",*p);
printf("%s\n",p);
return 0;
}
输出的结果是
a
abcdef
有一道笔试题:
int main()
{
char arr1[]= "abcdef";
char arr2[]= "abcdef";
const char* p1 ="abcdef";
const char* p2 ="abcdef";
if(arr1 == arr2)
{
printf("hehe\n");
}
else
{
printf("haha\n");
}
if(p1 == p2)
{
printf("hehe\n");
}
else
{
printf("haha\n");
}
return 0;
}
输出的结果是
haha
hehe
为什么输出haha?
arr1 与 arr2 是两个数组,创建了两个不同的空间,所以两个数组的首元素地址也不相同。
为什么输出hehe?
p1与p2指向的是同一个常量字符串,并且内容都是不可修改的。C会把常量字符串储存到单独的一个内存区域,当几个指针指向同一个字符串的时候,他们实际指向同一块内存,所以p1,p2指向的是一个空间,所以是相等的。
主体是数组
int* arr[10];//整型指针的数组
char* arr2[4];//一级字符指针的数组
char** arr3[5];//二级字符指针的数组
int main()
{
char arr1[] = {1,2,3,4,5};
char arr2[] = {2,3,4,5,6};
char arr3[] = {3,4,5,6,7};
const char* parr []= {arr1, arr2 ,arr3};
int i =0;
for(i = 0; i < 3 ; i++)
{
int j = 0;
for(j = 0; j <5; j++)
{
printf("%d", *(parr[i]+j));
}
printf("\n");
}
}
主体是指针
数组指针,能够指向数组的指针
int main()
{
int* p =NULL;//p是整型指针,指向整型的指针,存放整型的地址
char* pc = NULL;//pc是字符指针,指向字符的指针,存放字符的地址
int arr[10]={1,2,3,4,5,6,7,8,9,10};
int(*p)[10] = &arr;//数组的地址要存起来
//上面的p就是数组指针,p先和*结合,说明p是一个指针变量,然后指向的是一个大小为10个整型的数组
return 0;
}
void print(int arr[3][5],int x ,int y)
{
int i = 0;
int j =0;
for(i = 0; i<x ;i++ )
{
for(j=0; j<y; j++)
{
printf("%d ", arr[i][j])
}
}
}
void print(int (*pa)[5],int x ,int y)
{
int i = 0;
for(i = 0; i<x ;i++ )
{
for(j=0; j<y; j++)
{
printf("%d ", *(*(pa+i)+j));
}
}
int main()
{
arr[3][5]= {{1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7}};
print(arr,3,5);//参数是数组的形式
printf2(arr,3,5);//参数是指针的形式
}
输出的结果都是
12345
23456
34567
由上述的代码可知
printf("%d ",p[i][j]);
printf("%d ",*(p[i]+j));
printf("%d ",*(*(p+i)+j));
printf("%d ", *(p+i)[j]); //四种方式都等价
int arr[5];
arr是一个5个元素的整型数组
int* parr1[5];
parr1是一个数组,数组内有5个元素,每一个元素的类型是Int* ,parr1是一个指针数组
int (*parr2)[5];
parr2是一个指针,该指针指向一个5个元素的整型数组
int(*parr3[10])[5];
parr3是一个数组,该数组有10个元素,每一个元素是一个数组指针
该数组指针指向的数组有5个元素,每个元素的类型是int
一维数组传参
void test(int arr[])
{}
void test(int arr[10])
{}
void test(int* arr)
{}
void test2(int *arr[20])
{}
void test2(int **arr)//所有函数的传参都是正确的
{}
int main()
{
int arr[10] = {0};
int *arr2[20] = {0};
test(arr);
test2(arr2);
return 0
}
二维数组传参
void test(int *arr)//err
{}
void test(int* arr[5])//err
{}
void test(int (*arr)[5])//正确
{}
void test(int **arr)//err
{}
int main()
{
int arr[3][5]={0};
test(arr);
}
一级指针传参
void print(int *p , int sz)
{
int i = 0;
for(i=0; i<sz; i++)
{
printf("%d ",*(p+i));
}
}
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int *p =arr;
int sz = sizeof(arr)/sizeof(arr[0]);
print(p,sz);
}
思考:test和test2能接收什么参数
void test(int* p)
{}
void test2(char* p)
{}
int a =10;
test(&a);
//或者
int a =10;
int *p =&a;
test(p);
//test2同理
二级指针传参
void test(int** ptr)
{
printf("num= %d\n", **ptr);
}
int main()
{
int n =10;
int* p =&n;
int **p =&p;
test(pp);
test(&p);
int* arr[10];
test(arr);//指针数组也可以
return 0;
}