本周对c语言的指针、函数进行了系统的学习。主要遇到以下几个问题:+
1、指针表示数组的几种方式;一维数组和二维分别阐述;
2.数组指针、指针数组。二者的区别;
3.函数指针、指针函数,二者的区别;
4.什么是回调函数;
5.实参与形参的概念;
6.地址传参 和 数值传参的区别和用法;
7.报错:case label not within a switch statement;
1、指针表示数组的几种方式;一维数组和二维分别阐述。
1.1)一维数组:
1)&a[0]、&a[1]、 .... &a[i] //每个元素的起始地址
2)a、a+1、..... a+i //每个元素的起始地址
3)&a //表示数组的起始地址(&a+1 偏移一个数组的大小)
1.2)二维数组:
a[0]、a[1]、a[2] //表示第1维数组的三个元素——a[0][0~3] 、a[1][0~3] 、a[2][0~3];
&a[0]、&a[1]、&a[2] //表示第1维数组每个元素的起始地址,或者理解成每一行的起始地址;
a、a+1、a+2 //表示第1维数组每个元素的起始地址(同上一行);
a[0] :对于第一数组数组来说是第一个元素,但又是一个一维数组, 并且a[0]可以理解为第一行一维数组的数组名!
a[0][0]、a[0][1]、 a[0][2]、 a[0][3] //表示第一行的一维数组 每一个元素;
&a[0][0]、&a[0][1]、&a[0][2]、&a[0][3] //表示第一行一维数组 每一个元素的起始地址;
a[0]、a[0]+1、a[0]+2、a[0]+3 //表示第一行一维数组每一个元素的起始地址(同上一行);
1.3)指针操作一维数组
p++
p+i
p[i]
1.4)指针操作二维数组
p //是一个数组指针,保存二维数组第一行的起始地址
p+i //每一行的起始地址
*(p+i) //每一行第一个元素的起始地址
*(p+i)+j //每一行每一个元素的起始地址
*(*(p+i)+j) //每一行的每一个元素
2、数组指针、指针数组。二者的区别
2.1)数组指针
2.1.1)本质是一个指针变量,保存数组的起始地址;
2.1.2)数组指针语法:每个元素的类型 (*p) [元素个数] eg:int (*p) [8] ;
2.1.3)int (*p)[8] : 表示p是一个指针变量,保存有8个元素,每个元素是整型的数组的起始地址;
2.2)指针数组
2.2.1)本质就是一个数组,每一个元素都是指针类型的;
2.2.2)eg:int* a[5] = {&x, &y, &z, &w, &u};
3.函数指针、指针函数,二者的区别
3.1)函数指针
3.1.1)本质是一个指针变量,保存函数的入口地址;
3.1.2)语法: 返回值类型 (*pfun)(参数表); eg:
int (*p)(int , double); //p是一个函数指针,保存有两个参数,分别是整型和浮点类型, 返回值是整型函数的入口地址
ps: 函数名就是函数的入口地址;
3.3.3)函数调用的方式:
(1)直接通过函数名调用;
(2)回调函数: 使用函数指针调用函数(参数表);
3.2)指针函数
3.2.1)本质就是一个函数, 返回值是指针类型的函数;
ps: 如果返回值是指针类型,要返回一个有效的地址,返回局部变量的地址是没有意义的。
3.2.2) eg:int* func();
4.什么是回调函数
简单来说就是调用函数时其中一项参数是另一个函数(类似嵌套)。具体用法见以下博主文章:
C语言回调函数详解(全网最全)_小熊coder的博客-CSDN博客_c语言回调函数
5.实参与形参的概念
简单来说,实参是出现在主函数中的,传递给函数的参数。形参是出现在函数定义中的。
注意:1、实参可以是常量、变量、表达式、函数等;
2、实参的个数,类型应与形参一一对应,并且实参必须要有确定的值。
3、形参本身不占用空间, 只有调用函数时,才会为形参分配空间。
具体用法见以下博主文章:
形参和实参的区别_IT_小默的博客-CSDN博客_形参和实参是什么
6. 地址传参 和 数值传参 的区别和用法
1、如果只需要实参中的数据参与运算,不需要改变实参中的内容,地址传参和数值传参都可以;
2、如果要修改形参内容, 必须选择地址传参;
6.1)数值传参
将数值直接传入函数中;
#include <stdio.h>
void func(int x) //接收数据后,未实现功能,仍返回a的值
{
x = 10;
return ;
}
int main()
{
int a = 0;
func(a); //将数据直接传入函数中
printf("a = %d\n", a);
return 0;
}
6.2)地址传参
通过地址传参,可以传入,也可以传出;
//实现x,y的相加的几种用法
#include <stdio.h>
int func1(int x, int y)
{
int result = x+y; //数值传参;
return result;
}
/
int func2(int *px, int *py)
{
int result ; //地址传参
result = *px + *py; //通过指针传入参数
return result;
}
/
void func3(int x, int y, int *pret)
{ //地址传参
*pret = x+y; //通过指针传出参数
}
/
int main()
{
int a = 1, b=2;
int ret;
ret = func1(a, b);
ret = func2(&a, &b); //通过指针传入参数
func3(a, b, &ret); //通过指针传出参数
return 0;
}
7.编译时报错:case label not within a switch statement;
问题描述:使用switch语句,编译后报错,显示上述报错信息;
产生原因:1.是否在switch前加了分号;
2.case有没有用大括号括起来;
解决方案:switch(){ } ,将括号补充完整即可。