注:此博客仅为本人在学习过程中总结的容易遗忘、或者容易混淆、以及本人不会的一些知识点,仅供复习参考。
直接访问与间接访问
- 取址运算符&
- 间接运算符*
直接访问:即通过变量名直接访问
间接访问:通过变量的地址进行访问
指针与指针变量
指针:变量(常量)的地址
指针变量:存放指针(地址)的变量
*指针变量只能存放地址值,不能将整数(或者任何非地址类型的数据)赋给指针变量
易错点
int a, *p;
p = &a;
- (p)++相当于a++,如果没有括号,就成了p++,++和为同一优先级,但结合方向为自右向左,因此他相当于(p++)
数组与指针
- 引用一个数组元素可以用:
(1)下标法,如:a[i];
(2)指针法,如*(a+1);
注:数组名即“翻译为数组第一个元素的地址!” - 如果有一个实参数组,想在函数中改变次数组中元素的值,实参与形参有四种情况:
(1)形参实参都为数组名
void f(int x[], int n){
...
}
void main(){ //主函数
int a[10];
f(a,10);
}
(2)实参用数组名,形参用指针
void f(int *a, int n){
...
}
void main(){
int a[10];
f(a, 10);
}
(3)实参用指针变量,形参用数组名
(4)实参和形参都用指针变量
指向多维数组元素的指针
- int (*p)[4]
- 他表示p是一个指针变量。指向包含4个元素的一维数组。是行指针
- 二维数组的数组名也是行指针
因此:
int main(){
int a[5][5];
int (*p)[5] = a;
}
访问数组元素a[i][j]的方法:
- 纯下标法:a[i][j]
- 纯指针法:((a+i)+j)
- 混搭法1:*(a+i)[j]
- 混搭法2:*(a[i]+j)
字符串与指针
- 字符数组和字符指针的区别:
相同点:都能实现字符串的存储和运算
不同点:
1.字符数组由若干个元素组成,每个元素中存放一个字符,而字符指针变量存放的是地址
2.赋值方式上的不同点:字符数组不能用赋值运算符直接赋值,但字符指针可以。赋给a的不是字符,而是字符串的第一个元素的地址。
函数指针
函数指针的定义方法:
将函数名换成(*p),函数的返回值类型不变,参数类型不变
int fun(int a, int b){
...
}
int main(){
int (*p)(int, int) = fun;
}
用途:
1.将函数作为参数,通过函数指针来实现函数地址的传递,这样在被调用的函数中使用实参函数。
举个例子:
void sub(int (*x1)(int), int (*x2)(int, int)){
int a,b,i,j;
a = (*x1)(i);
b = (*x2)(i, j);
...
}
这段代码的原理可以归纳为:有一个名为sub的函数,定义了x1,x2为指向函数的指针变量。
返回指针值的函数
举个例子:
int *a(int x, int y){
...
}
和其他函数不同的点为:此函数返回的值为指针类型。
易混淆:
指针函数:函数的返回值类型为指针类型
函数指针:指向函数的指针
那么,如何定义一个函数指针指向返回指针值的函数呢?
易错点
int *fun(int a, int b){
...
}
//谨记规则:返回类型不变,即为(int *),剩下的就不写了
int main(){
int *(*p)(int, int) = fun;
}
指针数组
概念:数组的元素为指针
作用:可以作为main函数的形参。
补充:
main函数的参数:
void main(int argc, char *argv[]);
main函数是由操作系统调用的。不能在程序中得到,从命令行中得到
二级指针
指向指针的指针,定义方法:
int **p;
零散知识点整理
1.野指针
在这里穿插野指针的概念,野指针就是在新定义一个指针变量,该变量没有初始化或者赋值时,其值为一个随机值(不知道指向哪里)
2.会让程序报段错误的三种情况
(1)访问非法内存
(2)修改只读常量
(3)数组越界过多
3.void类型指针
例:
void *p;
表示指针变量不指向一个确定的类型数据,它的作用仅仅是存放一个地址。
void指针可以指向任何数据类型。也就是说,可以用任何数据类型的指针直接给void指针赋值。如果需要将void指针的值赋给其他类型,需要进行强制类型转换。
有关指针的总结
学习心得
这周我们学习到了C语言最令人生畏的部分——指针,通过这两天的学习,指针部分给我的印象可以用复杂、易混、灵活(难用)这么几个词来形容。在课堂中做的小测验也经常出错,和前面的知识完全感觉不一样,因此我更应该多刷题,多练习,以此来战胜困难。
加油
奥利给!