创建网站时可使用的数据库有,十大编程教育培训机构,苏州建行网站,四川门户网站建设C语言程序设计笔记---016 C语言指针进阶前篇1、字符指针2、指针数组2.1、指针数组例程1 -- 模拟一个二维数组2.2、指针数组例程2 3、数组指针3.1、回顾数组名#xff1f;3.2、数组指针定义与初始化#xff08;格式#xff09;3.3、数组指针的作用 --- 常用于二维数组3.4、数… C语言程序设计笔记---016 C语言指针进阶前篇1、字符指针2、指针数组2.1、指针数组例程1 -- 模拟一个二维数组2.2、指针数组例程2 3、数组指针3.1、回顾数组名3.2、数组指针定义与初始化格式3.3、数组指针的作用 --- 常用于二维数组3.4、数组指针 --- 二维数组的应用 4、数组的参数探究 --- 指针参数作为参数4.1、一维数组传参4.2、二维数组传参4.3、指针传参 5、函数指针5.1、函数指针初始化格式 6、巩固知识点6.1、解释以下代码16.2、解释以下代码2 7、结语 C语言指针进阶前篇
前言 什么是指针 指针是编程语言中的一个对象利用地址它的值直接指向存在电脑存储器中另一个地方的值。 由于通过地址能找到所需的变量单元可以说地址指向该变量单元。因此将地址形象化的称为“指针” 即能通过它能找到以它为地址的内存单元 另外平时口语中说的指针通常指的是指针变量是用来存放内存地址的变量。
/知识点汇总/ 1.指针变量就是变量用来存放地址地址唯一标识一块内存空间 2.指针的大小是固定的4/8个字节32位/64位、 3.指针是有类型的指针的类型决定了指针±整数的步长以及指针解引用的权限、 4.指针的运算指针加减整数偏移量指针减指针是指针和指针之间的元素个数指针关系运算指针大小比较 详见指针初阶 1、字符指针
指针就是地址口语中说的指针指的是指针变量 整型指针指向整型数据的指针 字符指针就是指向字符型数据的指针变量
#include stdio.h
int main()
{char ch w;char* pc ch;char* p abcdef;//这里的字符串等价于表达式然后返回的结果是第一个字符的地址可理解为数组//注意的是这里的“abcdef”属于常量表达式不可改变printf(%c\n,abcdef[3]);//d//类似于数组名 --- “abcdef” 所以可理解为数组形式const* pd abccdef;printf(%s\n, pd);//abcdefprintf(%c\n, *pd);//areturn 0;
}注意的是 (1)、这里的字符串等价于表达式然后返回的结果是第一个字符的地址可理解为数组 (2)、这里的“abcdef”属于常量表达式不可改变
例题
#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(1 to 2 same\n);}else{printf(1 to 2 not same\n);}if (str3 str4){printf(3 to 4 same\n);}else{printf(3 to 4 not same\n);}if (str3 str4){printf(3 to 4 same\n);}else{printf(3 to 4 not same\n);}return 0;
}小结 (1)、str1 与 str2 是两个不同的空间地址所以不相等 (2)、str3 与 str4 由于保存的是同一个常量表达式所以它们指向的地址相同则得到的值相同但是str3 和str4 本身的地址是不同的
2、指针数组
字符数组 – 存放字符的数组 整型数组 – 存放整型的数组 指针数组 – 存放指针的数组存放在数组中的元素是指针类型 如 int* arr[5]; char* ch[6]; 2.1、指针数组例程1 – 模拟一个二维数组
#include stdio.h
int main()
{int arr1[] { 1,2,3,4,5 };int arr2[] { 2,3,4,5,6 };int arr3[] { 3,4,5,6,7 };//int* int* int*//指针数组int* arr[] {arr1,arr2,arr3};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);}return 0;
}2.2、指针数组例程2
#include stdio.h
int main()
{//指针数组char* arr[5] {hello bit,hehe,abcf,cojag,waofrdf};int i 0;for (i 0; i 5; i){printf(%s\n,arr[i]);}return 0;
}3、数组指针
指针数组 ---- 是数组是存放指针的数组 数组指针 — 是指针 字符指针 — 是指向字符的指针 整型指针 – 指向整型的指针 浮点型指针 – 指向浮点数的指针
3.1、回顾数组名
数组名是数组首元素的地址但是存在两个例外sizeof(数组名)数组名 两个例外的数组名表达的是整个数组的地址
数组指针 — arr 虽然与首元素地址值相同但进行指针运算时±发现加减的整个数组的大小字节 同时指针类型决定了指针1到底几个字节步长
#include stdio.h
int main()
{int arr[10];printf(%p\n,arr);printf(%p\n,arr1);printf(%p\n, arr);printf(%p\n, arr 1);printf(%p\n, arr[0]);printf(%p\n, arr[0] 1);printf(%p\n, arr[0]);printf(%p\n, arr[0] 1);return 0;
}3.2、数组指针定义与初始化格式
#include stdio.h
int main()
{int arr[10] { 0 };//int* p arr;int(*p)[10] arr;//p是用来存放数组的地址的p就是数组指针char* arr2[5];char* (*pc)[5] arr2;//(*pc)说明pc是一个指针类型(*pc)[5],表示数组指针char* 表示该数组类型属于字符指针类型//int arr3[] { 1,2,3 };//int(*p3)[] arr3;//数组指针的[]操作符的参数必须指明否则报错return 0;
}3.3、数组指针的作用 — 常用于二维数组
#include stdio.h
int main()
{int arr[10] { 1,2,3,4,5,6,7,8,9,10 };//数组指针int(*p)[10] arr;int i 0;for(i0;i10;i){printf(%d ,(*p)[i]);}//指针变量int* p arr;int i 0;for (i 0; i 10; i){printf(%d , p[i]);}return 0;
}3.4、数组指针 — 二维数组的应用
二维数组的数组名是首元素的地址即数组指针的首元素地址是第一行的地址
#include stdio.h
//二维数组传参也是二维数组的形式
//void print(int arr[3][5], int row, int col)//形参是数组形式
//{
// 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 (*p)[5], int row, int col)//形参是指针形式,指向第一行
{int i 0;for (i 0; i 3; i){int j 0;for (j 0; j 5; j){printf(%d ,p[i][j]);}printf(\n);}
}
int main()
{int arr[3][5] { {1,2,3,4,5},{2,3,4,5,6},{6,7,8,9,10} };print(arr,3,5);//二维数组传参行列return 0;
}4、数组的参数探究 — 指针参数作为参数
4.1、一维数组传参
#include stdio.hvoid 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、二维数组传参
#include stdio.hvoid test(int arr[3][5])//ok
{}
void test(int arr[][])//No,列不可以省
{}
void test(int arr[][5])//ok
{}
void test(int *arr)//No,不能以一维数组接收二维数组因为二维数组的首元素地址是第一行的地址而不是第一个元素的地址
{}
void test(int* arr[5])//No类型不同int* 与int
{}
void test(int (*arr)[5])//ok数组指针指向第一行
{}
void test(int **arr)//No,二级指针用于指向一级指针的地址
{}int main()
{int arr[3][5];test(arr);return 0;
}4.3、指针传参
一级指针传参 一级指针传参时形参写成一级指针形式
#include stdio.h
void print(int* p, int sz)//一级指针传参时形参写成一级指针形式就可以了
{int i 0;for (i 0; i sz; i){printf(%d\n,*(pi));}
}
int main()
{int arr[10] { 1,2,3,4,5,6,7,8,9,10 };int* p arr;int sz sizeof(arr) / sizeof(arr[0]);//一级指针p传给函数作形参print(p,sz);return 0;
}思考扩展1 当我们遇见一个函数的形参是一级指针的时候考虑函数的实参可以传什么 答只要是可以传递的对应类型的地址/一级指针变量就可以以及数组名也行。
二级指针传参 二级指针传参时形参写成二级指针形式
#include stdio.hvoid 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;
}思考扩展2 当我们遇见一个函数的形参是一级指针的时候考虑函数的实参可以传什么 答只要是可以传递的对应类型的一级指针地址/二级指针变量就可以一级指针类型的数组名也行。
5、函数指针
数组指针 – 指向数组的指针 – 存放的是数组的地址 — 数组名就是整个数组的地址 函数指针 – 指向函数的指针 — 存放的是函数的地址
如何取得函数的地址呢也是通过 函数名吗 答操作符加函数名即可
5.1、函数指针初始化格式
#include stdio.hint Add(int x, int y)
{return (x y);
}int main()
{//函数名就是函数的地址//函数名也是函数的地址printf(%p\n, Add);printf(%p\n, Add);//均表示函数的地址//函数指针//int (*pf1)(int , int) Add;//pf1就是函数指针变量int (*pf2)(int, int) Add;//pf2同样是函数指针变量int ret (*pf2)(2, 3);//因为Add与Add等价//常规写法//int ret Add(2,3);//所以*号就可以省略//int ret pf2(2,3)printf(%d\n,ret);
}6、巩固知识点
6.1、解释以下代码1
int arr[5];//arr是一个存放5个整型数据的数组
int* parr1[10];//parr1是一个数组数组的10个元素类型是int*
int(*parr2)[10];//parr2是一个数组指针该指针指向的数组指向数组的10个元素类型是int
int(*parr3[10])[5];//parr3是一个数组是存放数组指针的10元素的数组存放的这个数组指针指针指向的5个元素是int类型6.2、解释以下代码2
#include stdio.h
int main()
{(*(void(*)())0)();//整体是一个函数调用//(void(*)()函数指针类型//(void(*)()) 强制类型转换为函数指针类型//(*(类型)0)(); --- 所以这段代码表示//调用0地址处的函数这个函数没有参数且返回值类型为void省略不写void (*signal(int, void(*)(int)))(int);//整体是一个函数声明//void(*)(int)函数指针作为参数//signal(int, void(*)(int)) --- 函数一个参数是int类型一个参数是函数指针类型返回值类型也是作为函数指针类型//(*signal(int, void(*)(int))) --- 函数指针//(*signal(int, void(*)(int)))(int) --- 函数指针参数是一个int类型参数//void (*signal(int, void(*)(int)))(int) -- 一个返回值类型为空参数是一个整型的函数指针的声明//所以这段代码表示//是一个函数声明声明的是signal函数signal函数的参数有两个一个是int类型一个是函数指针类型该类型是void(*)(int),该函数指针指向的函数参数类型是int类型返回值类型为void//signal函数的返回值类型也是函数指针类型该类型是void (*)(int),该函数指针指向的函数参数类型是int类型返回值类型为void//利用typedef 对这段代码简化:typedef void(*pfun_t)(int);//typedef 对函数指针类型重命名时被重名的变量名放在*面即pfun_t的位置pfun_t signal(int, pfun_t);return 0;
}7、结语
C语言指针进阶前篇到此结束啦 未完待续… 半亩方糖一鉴开天光云影共徘徊。 问渠哪得清如许?为有源头活水来。–朱熹观书有感