内容索引
1.
字符指针
2. 指针数组
3. 数组指针
4.
数组传参和指针传参
字符指针
#include <stdio.h>
int main()
{
char ch = 'w';
char* pc = &ch;//pc就是字符指针
char* p = "abcdef" ;//是把字符串首字符的地址存放在p中
//=右边表达式的值是首字符的地址(常量字符串 不能修改)
//可以理解为 :char arr[] = "abcdef" ;
// char*p = arr;(p指向的是数组的首元素 区别是arr数组是可以修改的)
return 0;
}
例题:
#include <stdio.h>
int main()
{
char str1[] = "hello bit.";
char str2[] = "hello bit.";
const char *str3 = "hello bit.";
const char *str4 = "hello bit.";
if(str1 ==str2)
printf("str1 and str2 are same\n");
else
printf("str1 and str2 are not same\n");
if(str3 ==str4)
printf("str3 and str4 are same\n");
else
printf("str3 and str4 are not same\n");
return 0;
}
运行结果:
为什么是这样的结果呢?
- 数组可修改,str1 str2分别指向一个数组空间 这两个数组不在同一个位置,故而两者首元素的地址不同
- 常量字符串不可修改 str3 str4指向相同的空间
- 那么&str3 &str4呢? 同str1 str2一样 两者不同
指针数组
指针数组
字符数组 —— 存放字符的数组
char arr1[10];
整型数组——存放整型的数组
int arr2[5];
指针数组——存放的就是指针
存放字符指针的数组——字符指针数组
char * arr3[5];
存放整型指针的数组——整型指针数组
int* arr[6];
#include <stdio.h>
int main()
{
char* arr[] = {"abcdef","hh","qwer"};
int i = 0;
for (i = 0;i < 3;i++)
{
printf("%s\n",arr[i]);
}
return 0;
}
分别是首元素a h q的地址
接下来我们再次看看初阶指针(二)中的这个例子:
运行结果:
ptr是一个存放整型指针的数组
注:
因为ptr[i] <==> *(ptr+i)
所以 ptr[i][j] <==> *(*(ptr+i)+j) <==>*(ptr[i]+j)
数组指针
类比:
整型指针——指向整型的指针
int a = 10;
int *p= &a;
字符指针——指向字符的指针
char ch = 'w';
char*pc = &ch;
数组指针——指向数组的指针
int arr[10];
int (*pa) [10]= &arr;//取出的是数组的地址
//注意 int *pa[10] 这样写是 存放指针的数组
char arr[10];
char(*pc)[10] = &arr;
int* arr[5];
int* (*p) [5] = &arr;
补充:&数组名 VS 数组名
数组名是首元素的地址,但是有两个例外:
- sizeof(数组名),数组名如果单独放在sizeof内部,这里的数组名表示整个数组,计算的是整个数组的大小
- &数组名,这里的数组名表示整个数组,取出的是整个数组的地址,从地址值的角度来讲和数组首元素的地址是一样的,但是意义不一样
#include <stdio.h>
int main()
{
int arr[10] = {0};
printf("%d\n",sizeof(arr));//40
printf("%p\n",arr);//int*
printf("%p\n",arr+1);//跳过一个元素 4
printf("%p\n",&arr);// int(*)[10]
printf("%p\n",&arr+1);//跳过整个数组
int (*p)[10] = &arr;//p是一个数组指针
}
arr+1 加了4 而&arr+1 DF0变成E18加了0x28<==>加了40
数组指针的使用
访问一维数组(不推荐)
一维数组传参
#include <stdio.h>
//形参是数组
//void print(int arr[10],int sz)
//{
// int i = 0;
// for(i = 0;i < sz;i++)
// {
// printf("%d ",arr[i]);
// }
// printf("\n");
//}
//形参是指针
void print(int *arr,int sz)
{
int i = 0;
for(i = 0;i < sz;i++)
{
printf("%d ",*(arr+i));
}
printf("\n");
}
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int sz = sizeof(arr)/sizeof(arr[0]);
print(arr,sz);
return 0;
}
二维数组传参
#include <stdio.h>
//形参部分是二维数组
//void print1(int arr[3][5],int r,int c)
//{
// int i = 0;
// for(i = 0;i < 3;i++)
// {
// int j = 0;
// for(j = 0;j < 5;j++)
// {
// printf("%d ",arr[i][j]);
// }
// printf("\n");
// }
//}
//形参部分是指针
void print(int (*arr)[5],int r,int c)
{
int i = 0;
for(i = 0;i < 3;i++)
{
int j = 0;
for(j = 0;j < 5;j++)
{
printf("%d ",*(*(arr+i)+j));
//二维数组:*(arr+0)-arr[0]-&arr[0][0]
//printf("%d ",arr[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};
//二维数组的数组名,也表示首元素的地址
//二位数组的首元素是第一行
//首元素的地址就是第一行的地址,是一个一维数组的地址
print(arr,3,5);
return 0;
}
特例代码:
int(*parr3[10])[5];
parr3是数组,数组中存放的指针,该指针指向的又是数组(相当于指针数组中存放的是数组指针)
数组参数和指针参数
一维数组传参
#include <stdio.h>
void test(int arr[])//ok?
{对}
void test(int arr[10])//ok?
{对}
void test(int *arr)//ok?
{对}
void test2(int *arr[20])//ok?
{对}
void test2(int **arr)//ok?
{对}
int main()
{
int arr[10] = {0};
int *arr2[20] = {0};
test(arr);
test2(arr2);
}
一维数组传参,形参可以是数组,也可以是指针
当形参是指针的时候,要注意类型
二维数组传参
void test(int arr[3][5])//ok?
{对}
void test(int arr[][])//ok?
{错}
void test(int arr[][5])//ok?
{对}
//总结:二维数组传参,函数形参的设计只能省略第一个[]的数字。
//因为对一个二维数组,可以不知道有多少行,但是必须知道一行多少元素。
//这样才方便运算。
void test(int *arr)//ok?
{错}
void test(int* arr[5])//ok?
{错}
void test(int (*arr)[5])//ok?
{对}
void test(int **arr)//ok?
{错}
int main()
{
int arr[3][5] = {0};
test(arr);
}
二维数组传参
参数可以是指针,也可以是数组
如果是数组,行可以省略,但是列不能省略
如果是指针,传过去的是第一行的地址,形参就应该是数组指针
一级指针传参
#include <stdio.h>
void print(int *p, int sz)
{
int i = 0;
for(i=0; i<sz; i++)
{
printf("%d\n", *(p+i));
}
}
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9};
int *p = arr;
int sz = sizeof(arr)/sizeof(arr[0]);
//一级指针p,传给函数
print(p, sz);
return 0;
}
思考:
当一个函数的参数部分为一级指针的时候,函数能接收什么参数?
int a;
print(&a,10);
int *p1 = a;
print(p1,10);
int arr[10];
print(arr,10);
二级指针传参
#include <stdio.h>
void test(int** ptr)
{
printf("num = %d\n", **ptr);
}
int main()
{
int n = 10;
int*p = &n;
int **pp = &p;
test(pp);
test(&p);
return 0;
}
思考:
当函数的参数为二级指针的时候,可以接收什么参数?
test(二级指针变量);
test(一级指针变量的地址);
int* arr[10];
test(arr);