大家好!指针的初阶内容我已经写好,可移步至我的文章:c语言进阶部分详解(指针初阶)_总之就是非常唔姆的博客-CSDN博客
基本内容我便不再赘述,直接带大家进入进阶内容:
在指针的类型中我们知道有一种指针类型为字符指针 char* ;
其一般的使用场景为:这样
#include<stdio.h>
int main()
{
char a = 'z';
char* pa = &a;
return 0;
}
还有这样:
int main()
{
char* arr = "hello";
printf("%s", arr);
return 0;
}
针对char* arr = "hello";这个语句,特别容易让各位以为是把字符串 hello放到字符指针 arr 里了,但是本质是把字符串 hello首字符的地址放到了arr中
下面来看一个例题加深理解:大家可以先思考一下再进行答案的比对
int main()
{
char str1[] = "hello";
char str2[] = "hello";
const char* str3 = "hello";
const char* str4 = "hello";
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;
}
答案:
各位对了吗?
示例:int num1 = 10, num2 = 20, num3 = 30; int *ptr[3] = {&num1, &num2, &num3}; // 声明一个包含3个整型指针的数组
用指针数组来模拟二维数组
int main()
{
int arr1[4] = { 1,2,4,5 };
int arr2[4] = { 2,2,5,5 };
int arr3[4] = { 1,1,4,4 };
int* pa[3] = { &arr1,&arr2,&arr3 };
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
{
printf("%d ", pa[i][j]);
}
printf("\n");
}
return 0;
}
示例:int arr[5] = {1, 2, 3, 4, 5}; int (*ptr)[5] = &arr; // 声明一个指向包含5个整数的数组的指针
int *p1[10]; int (*p2)[10];
int (*p)[10];为数组指针 //解释:p先和*结合,说明p是一个指针变量,然后指着指向的是一个大小为10个整型的数组。所以p是一个指针,指向一个数组,叫数组指针。 //这里要注意:[]的优先级要高于*号的,所以必须加上()来保证p先和*结合 int *p1[10];为指针数组 //解释:p先和[]结合,说明p是一个数组,然后数组的类型为int*
1.sizeof(数组名),这里的数组名表示整个数组,sizeof(数组名)计算的是整个数组的大小,单位是字节。 2.&数组名,这里的数组名表示整个数组,取出的是数组的地址
void print_arr(int(*arr)[5], int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
printf("%d ", arr[i][j]);
}
printf("\n");
}
}
int main()
{
int arr[3][5] = { 1,2,3,4,5,6,7,8,9,10 };
//数组名arr,表示首元素的地址
//但是二维数组的首元素是二维数组的第一行
//所以这里传递的arr,其实相当于第一行的地址,是一维数组(有五个元素)的地址
//可以数组指针来接收
print_arr(arr, 3, 5);
return 0;
}
理解:parr3[10]可知是一个数组,int (* )[5]是一个数组指针类型,所以总的看是一个存放数组指针类型的数组。
void test(int arr[])//可以 数组传参,形参是可以写成数组形式的
{}
void test(int arr[10])//可以
{}
void test(int* arr)//可以 数组传参的本质是传递了数组首元素的地址,形参也可以是指针
{}
void test2(int* arr[20])//可以
{}
void test2(int** arr)//可以 传过来的是int* 的地址,就用int**来接收
{}
int main()
{
int arr[10] = { 0 };
int* arr2[20] = { 0 };
test(arr);
test2(arr2);
}
形参为二维数组或者数组指针
//总结:二维数组传参,函数形参的设计只能省略第一个[]的数字。
//因为对一个二维数组,可以不知道有多少行,但是必须知道一行多少元素。
//这样才方便运算。
void test(int arr[3][5])//可以
{}
void test(int arr[][])//不可以:只能省略行,不能省略列
{}
void test(int arr[][5])//可以
{}
void test(int* arr)//不可以
{}
void test(int* arr[5])//不可以
{}
void test(int(*arr)[5])//可以
{}
void test(int** arr)//不可以
{}
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\n", *(p + i));
}
}
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9 };
int* pa = arr;
int sz = sizeof(arr) / sizeof(arr[0]);
//一级指针p,传给函数
print(pa, sz);
return 0;
}
就用二级指针来接收
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;
}
只要是一级指针的地址就行: int a=10; int* p=&a; int** pp=&p; test(&p); test(pp); int* arr[10]; 指针数组,首元素为一级指针,传过来首元素的地址 test(arr);
这次的内容梳理就先到这里了,我会加快更新后续内容的,感谢大家的支持!!!