
⭐博主: 清炒莲藕拌饭
⭐博客:(10条消息) 清炒莲藕拌饭的博客_CSDN博客-C语言领域博主
⭐专栏:(10条消息) C语言_清炒莲藕拌饭的博客-CSDN博客
⭐专栏介绍:包含从C语言初阶到进阶各各知识点进行讲解,用C语言写的各种小程序,大体围绕C基础为主的专栏;
🟡本篇博客介绍重点✒️
1. 字符指针
2. 数组指针
3. 指针数组
4. 数组传参和指针传参
5. 函数指针
1.字符指针🤔 前言回顾:
1. 指针就是个变量,用来存放地址,地址唯一标识一块内存空间。
2. 指针的大小是固定的4/8个字节(32位平台/64位平台)。
3. 指针是有类型,指针的类型决定了指针的+-整数的步长,指针解引用 *** 作的时候的权限。 4. 指针的运算。
前面我们应该也见过 char* 字符指针,一般出现下面使用情况:
int main()
{
char ch = 'w';
char *pc = &ch;
*pc = 'w';
return 0;
}
int main()
{
const char* pstr = "hello";//这里是把一个字符串放到pstr指针变量里了吗?
printf("%s\n", pstr);
return 0;
}
🤔 打印结果就是hello,那是不是pstr里面就存放的字符串hello呢?千万不要这样认为,指针变量都是存放地址的,pstr应该说是存放字符串首元素的地址,printf打印就会按照这个地址打印下去,遇到上面的代码看明白了我们来看下面这段代码:就会停止打印;
问打印结果是什么?
#includeint 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是什么意思,这个表达式其实表示在比较它们的地址是否相同,那么str1和str2它们是两个不相同的数组,地址怎么可能一样呢?而str3和str4它们都是字符常量,不需要在内存中开辟新的空间,它们的首地址都是指向字符‘h’的,所以地址肯定也一样;
💡 题解:
2.指针数组
指针数组就是一个存放指针类型的数组,它里面的元素都是指针类型;int* arr1[10]; //整形指针的数组
char *arr2[4]; //一级字符指针的数组
char **arr3[5]; //二级字符指针的数组
优先级理解:arr1先和[ 10 ]结合,说明这就是一个数组,数组的类型是它前面int *,说明这是一个指针数组,用来存放指针的;
它是指针,指向数组的指针,我们前面已经知道有int *pa 整型指针 , float *pb 浮点型指针,它们都是指向某个类型的指针,那么数组指针也一样,它指向的类型是一个数组;
⭐3.数组指针 3.1 数组指针的定义数组指针是什么?
arr1前面我们已经介绍过了,它是指针数组;
int * arr1[10] = { 0 };
int (* arr2)[10] = { 0 }; //arr1和arr2分别是什么?
arr2注意看它的(*arr2),这说明无论如何arr2已经和*结合了,这就表明arr2就是指针了而不是数组名了,因为它没有机会和[10]去结合了,而指向的类型就是int [10],所以我们叫它数组指针;
&arr和arr有什么不一样的吗?好像是一模一样的,arr是数组首元素地址&arr同样也是首元素地址,居然一样何必这么麻烦还要用&呢?
3.2 &数组名VS数组名注意💡:因为[ ]的优先级比*高,arr2会先和[10]结合,所以你如果想要的是一个数组指针就必须加上()让*和arr2先结合,这样才能保证arr2是一个数组指针;
int arr[10] = { 0 };
我的答案是NO! 编程讲究严谨,那么它的语法更是如此,存放的内容一样不代表它们意义就相等了,空口无凭下面我就带大家来研究&arr和arr的区别;
我们打印它们的地址确实一样
#includeint main() { int arr[10] = {0}; printf("%p\n", arr); printf("%p\n", &arr); return 0; } 运行结果:
但是我们来看下面这段代码:
这说明什么?&arr和arr虽然值一样,但是它们的意义肯定不一样,所以有些事我们不要被表象迷惑,事情有疑点那我们就刨根问底然后将它斩于马下;事实上&arr是代表数组所有元素的地址,但是总得有一个地址来表达它们,但是空间又有限不可能将所有的元素地址表达出来,所以还是使用了数组首元素来来代表它们,但是它的意义却不一样了;
#include
int main()
{
int arr[10] = { 0 };
printf("arr = %p\n", arr);
printf("arr+1 = %p\n", arr + 1);
printf("&arr= %p\n", &arr);
printf("&arr+1= %p\n", &arr + 1);
return 0;
}
运行结果:
🤔思考:
3.3数组指针的使用&arr大家可以仔细想一想它是什么?它是不是一个数组指针啊,确实是的,&arr所指向的就是arr整个数组,在本案例中它的类型是int (*)[10];
既然有数组指针这个东西那我们应该怎么使用呢?
数组的地址+1,跳过整个数组的大小,所以 &arr+1 相对于 &arr 的差值是40.
栗子1(不常用):
栗子2(常用):
#include
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,0};
int (*p)[10] = &arr;//把数组arr的地址赋值给数组指针变量p
//但是我们一般很少这样写代码
return 0;
}
学了指针数组和数组指针我们来一起回顾并看看下面代码的意思:
#include
void print_arr1(int arr[3][5], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
printf("%d ", arr[i][j]);
}
printf("\n");
}
}
void print_arr2(int(*arr)[5], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
int j = 0;
for (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 };
print_arr1(arr, 3, 5);
//数组名arr,表示首元素的地址
//但是二维数组的首元素是二维数组的第一行
//所以这里传递的arr,其实相当于第一行的地址,是一维数组的地址
//可以数组指针来接收
print_arr2(arr, 3, 5);
return 0;
}
在写代码的时候难免要把【数组】或者【指针】传给函数,那函数的参数该如何设计呢?
4.数组参数,指针参数int arr[5]; //整型数组
int *parr1[10]; //指针数组
int (*parr2)[10]; //数组指针
int (*parr3[10])[5]; //存放数组指针的数组
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
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);
return 0;
}
4.2 二维数组传参
🤔当一个函数的参数部分为一级指针的时候,函数能接收什么参数?4.3 一级指针传参
#include
void print(int *p, int sz)
{
int i = 0;
for(i=0; i
4.4 二级指针传参
#include
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;
}
🤔当函数的参数为二级指针的时候,可以接收什么参数?
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)