当前位置: 首页 > news >正文

房地产门户网站百度刷排名百度快速排名

房地产门户网站,百度刷排名百度快速排名,中英双语网站怎么做,江西企业网站建设内容小复习#x1f431;#xff1a; 字符指针:存放字符的数组 char arr1[10]; 整型数组:存放整型的数组 int arr2[5]; 指针数组:存放的是指针的数组 存放字符指针的数组(字符指针数组) char* arr3[5]; 存放整型指针的数组(整型指针数组) int* arr[6]; 下面进入学习了哦~… 内容小复习 字符指针:存放字符的数组 char arr1[10]; 整型数组:存放整型的数组 int arr2[5]; 指针数组:存放的是指针的数组 存放字符指针的数组(字符指针数组) char* arr3[5]; 存放整型指针的数组(整型指针数组) int* arr[6]; 下面进入学习了哦~ 文章目录前言一、字符指针面试题讲解二、指针数组1.字符指针数组2.整型指针数组三、数组指针**1.整型指针**:指向整型的指针**2.字符指针**:指向字符的指针**3.数组指针**:指向数组的指针**4.注意区分:arr 和arr**5.访问数组的三种形式(1)下标访问(2)指针访问(3)数组指针访问(不推荐)6.数组传参(1)一维数组传参,形参写成数组或者指针的形式I.写成数组的形式II. 写成指针的形式(2)二维数组传参I.形式参数写成数组的形式II.形式参数写成指针的形式7.分析代码(1)(2)(3)四、数组参数、指针参数1.一维数组传参以下test的写法可行吗?以下test2的写法可行吗?**二级指针简单说明**:**结论**:2.二维数组传参形参的部分可以这样写吗?**结论**:3.一级指针传参**思考**:4.二级指针传参**思考:**五、函数指针1.回顾一下指针的类型2.函数指针变量用来存放函数的地址3.通过函数指针调用它指向的函数总结:上述知识考察4.阅读两段有趣的代码**代码1****代码2**:六.函数指针数组知识点练习**写一个计算器能完成整数的-*/**在计算机基础上, 增加一些其他的功能: | ^ ||总结前言 1.指针就是个变量,用来存放地址,地址唯一标识一块内存空间 2.指针的大小是4或者8个字节(32位平台4个字节,64位平台8个字节) 3.指针是有类型的,指针的类型决定了指针±一个整数的长度有多少,指针解引用操作时候的权限 4.指针的运算 指针能够加减整数运算 指针能够解指针 指针能够进行关系运算,也就是地址的关系运算,比较大小 一、字符指针 字符指针不仅仅可以指向字符,还可以指向字符串. #define _CRT_SECURE_NO_WARNINGS 1 #includestdio.h int main() {char ch w;char* pc ch;//pc就是字符指针//1.char* pd abcdef; //abcdef表达式的值是首字符a的地址,p中实际上放的是a的地址//常量字符串不能修改//2.char arr[] abcdef;char* pf arr; //pf指向的是数组首元素的地址//arr数组是可以修改的//修改*pf w;printf(%s\n, arr);return 0; }注意: 在有一些编译器中下面的代码会报错,因为abcdef是常量字符串,本质上不能修改,将这个字符串交给p是很危险的,char p 没有保护起来,所以通过p万一去修改a,在运行的时候就会出错. char* pabcdef; *pw;解决办法: 加上const,意思是const修饰的是p,限制了p, 此时*p不能被修改 const char* pabcdef;所以即使是在vs2019中可以运行,但最好也在前面加上const 面试题讲解 #include stdio.h int main() {char str1[] hello world.;char str2[] hello world.;const char* str3 hello world.;const char* str4 hello world.;if (str1 str2)printf(str1 and str2 are same\n);elseprintf(str1 and str2 are not same\n);if (str3 str4)printf(str3 and str4 are same\n);elseprintf(str3 and str4 are not same\n);return 0; }分析: 拿hello world.分别初始化一个数组,是必然都会创建的.创建两个数组在内存中的位置一定是有区别的.所以str1和str2不相等 对于const 修饰的常量字符串,不能被改,没有必要存两份,所以str3和str4里面存的是一样的 该题拓展: 下面的代码相等吗? if(str3str4){ }答案:不相等.因为变量str3和str4是不在一个空间里面的,取str3的地址和str4的地址肯定不相等. 与上面的区别是:数组名是数组里面首元素的地址,而str3取得是变量str3的地址 二、指针数组 指针数组:存放的是指针的数组 存放字符指针的数组(字符指针数组) char* arr3[5]; 存放整型指针的数组(整型指针数组) int* arr[6]; 1.字符指针数组 int main() {char* arr[] { abcdef,hehe,qwer };for (i 0; i 3; i) {printf(%s\n, arr[i]);}return 0; }2.整型指针数组 int main() {int arr1[] { 1,2,3,4,5 };int arr2[] { 2,3,4,5,6 };int arr3[] { 3,4,5,6,7 };//数组首元素地址是整型地址//arr是一个存放整型指针的数组int* arr[] { arr1,arr2,arr3 };int i 0;for (i 0; i 3; i) {//arr[i]拿到的是arr1/arr2/arr3的地址//加上一个j再解引用就可以拿到里面的各个元素int j 0;for (j 0; j 5; j) {//arr[i][j]也可以写成arr[i]jprintf(%d , arr[i][j]);//printf(%d , *(arr[i] j));}printf(\n);}return 0; } 三、数组指针 类比上面的定义: 1.整型指针:指向整型的指针 int a 20;int* p a;2.字符指针:指向字符的指针 char ch w;char* pc ch;3.数组指针:指向数组的指针 数组名是首元素的地址,有两个例外: 一是sizeof内部单独放一个数组名 另一个是取地址数组名,这个取出的是数组的地址 int arr[10]; arr; //取出的是数组的地址 pa说明pa是指针,当去掉pa时剩下int [10],说明pa指向的是数组 int arr[10];int(*pa)[10] arr;char arr2[10];char(*pc)[10] arr2;4.注意区分:arr 和arr 绝大多数情况下,数组名是数组首元素的地址 但是有两个例外: 1.sizeof(数组名) sizeof内部单独放一个数组名的时候,数组名表示整个数组,计算得到的是数组的总大小 2.arr 这里的数组名表示整个数组,取出的是整个数组的地址,从地址值的角度来讲和数组首元素的地址一样,但是意义不一样 int main() {int arr[10] { 0 };printf(%p\n, arr);printf(%p\n, arr[0]);printf(%p\n, arr);return 0; }int main() {int arr[10] { 0 };printf(%p\n, arr);printf(%p\n, arr1);printf(%p\n, arr[0]);printf(%p\n, arr[0]1);printf(%p\n, arr);printf(%p\n, arr1);return 0; }printf(“%p\n”, arr); printf(“%p\n”, arr1); 数组名1,数组名的类型是int*,int类型的指针1之后跳过的是4个字节 printf(“%p\n”, arr[0]); printf(“%p\n”, arr[0]1); arr[0]的类型也是int,int*类型的指针1之后跳过的是4个字节 printf(“%p\n”, arr); printf(“%p\n”, arr1); arr的类型是指向数组的指针,它的类型是int( * )[10],1的时候跳过整个数组的长度 5.访问数组的三种形式 (1)下标访问 (2)指针访问 (3)数组指针访问(不推荐) int main() {int arr[10] { 1,2,3,4,5,6,7,8,9,10 };int i 0;int sz sizeof(arr) / sizeof(arr[0]);//使用指针来访问int* p arr;for (i 0; i sz; i) {printf(%d , *(p i));}//下标访问的形式访问数组for (i 0; i sz; i) {printf(%d , arr[i]);}//取出整个数组的地址,与上面访问数组的结果相同,但是不易于理解,不推荐int(*pa)[10] arr; //pa相当于arr *pa相当于*arr也就是*paarr for (i 0; i sz; i) {printf(%d , *((*pa) i));//*pa是首元素的地址//printf(%d , (*pa)[i]);与上面等同}}6.数组传参 (1)一维数组传参,形参写成数组或者指针的形式 I.写成数组的形式 void print(int arr[10],int sz){int i 0;for (i 0; i sz; i) {printf(%d , arr[i]);}printf(\n);} int main() {int arr[10] { 1,2,3,4,5,6,7,8,9,10 };int sz sizeof(arr) / sizeof(arr[0]);print(arr, sz); }II. 写成指针的形式 void print(int *arr, int sz) {int i 0;for (i 0; i sz; i) {printf(%d , arr[i]);}printf(\n);} int main() {int arr[10] { 1,2,3,4,5,6,7,8,9,10 };int sz sizeof(arr) / sizeof(arr[0]);print(arr, sz); }(2)二维数组传参 I.形式参数写成数组的形式 void print(int arr[3][5],int r,int c) {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);} } //二维数组传参 int main() {int arr[3][5] { 1,2,3,4,5,2,3,4,5,6,3,4,5,6,7 };//封装一个函数打印二维数组//需要传数组,行和列print(arr, 3,5);return 0; }II.形式参数写成指针的形式 二维数组的数组名也表示首元素的地址. 二维数组其实是一维数组的数组. 每一行都是一个元素 二维数组的首元素是? 二维数组的首元素是第一行 首元素的地址就是第一行的地址 第一行的地址是一个一维数组的地址 形式参数要用数组指针int (*arr)[5] //二维数组传参,形式参数用指针表示 void print(int (*arr)[5], int r, int c) {int i 0;for (i 0; ![在这里插入图片描述](https://img-blog.csdnimg.cn/d69157ed8d1c428ea0d1a878b4d476c0.png) i 3; i) {int j 0;for (j 0; j 5; j) {//printf(%d , *(*(arri)j)); //等价于下一行的写法printf(%d ,arr[i][j]);}printf(\n);} } //二维数组传参 int main() {int arr[3][5] { 1,2,3,4,5,2,3,4,5,6,3,4,5,6,7 };//封装一个函数打印二维数组//需要传数组,行和列print(arr, 3, 5);return 0; }注意: 7.分析代码 (1) int *parr1[10];parr1和[]结合,是数组,十个元素,每个元素是int*类型,所以它是指针数组 (2) int(*parr2)[10];parr2是一个指针,指向的是数组,数组十个元素每个元素是int类型,所以它是数组指针 (3) int(*parr3[10])[5];parr3首先和[]结合是数组,数组名和数组个数parr3[10]除外,剩下的就是数组元素的类型int( * )[5],int( * )[5]说明是指针,指针指向的是5个元素的数组,每个元素的类型是int parr3是数组,数组中存放指针,该指针又指向数组 可以理解为指针数组存放的是数组指针 四、数组参数、指针参数 1.一维数组传参 int main() {int arr1[10] { 0 };int *arr2[20] { 0 };test(arr1);test2(arr2); }以下test的写法可行吗? (1) void test(int arr[]) {}ok. 数组的大小可以不写,因为虽然这里传过来的是一个数组,但是不会在函数里面真的创建一个数组,不需要大小 (2) void test(int arr[10]) {}ok 形参的数组可以写大小 (3)数组名传过去,形参的部分写成指针行不行? void test(int *arr) {}行还是不行取决于传过去的是什么 数组名表示首元素的地址,首元素是int的地址,整型的地址就要放到整型的指针里面 ok 以下test2的写法可行吗? (1) void test2(int* arr[20]) {}arr2数组名表示首元素的地址,一维数组传参,形参部分写成数组,可行 数组20个元素,每个元素是int*类型 ok (2) 能不能这样写? void test2(int **arr) {}因为这个数组每个元素都是int*,数组名表示首元素地址,就是一个int*的地址(一级指针的地址),应该放到二级指针变量里边去 ok 二级指针简单说明: 二级指针是指向指针的指针. 它的作用是为了获取指针的存放地址. 首先任何值都有地址,一级指针的值虽然是地址,但这个地址作为一个值也需要空间来存放,二级指针就是来存放这一空间的地址. 结论: (1)一维数组传参,形参可以是数组,也可以是指针的. (2)当形参是指针的时候,要注意类型 2.二维数组传参 int main() {int arr[3][5] { 0 };test(arr); }形参的部分可以这样写吗? (1) void test(int arr[3][5]) {}ok 二维数组传参还写成二维数组的形式,3行5列,没问题 (2)可以省去二维数组形参的行和列的长度吗? void test(int arr[][]) {}不行! 行可以省略,列不可以省略. 因为需要知道一行有几个元素,但是有几行不关心,只有找完一行才能找到下一行. 二维数组的内存是连续存放的.只有知道一行有几个元素的时候,才能知道第二行在哪里,第三行在哪里. 应该写成: void test(int arr[][5]) {}(3) void test(int* arr) {}不行! 二维数组首元素的地址相当于是它第一行的地址,第一行是五个整型的数组.相当于首元素的地址是一维数组首元素的地址,这里形参写一个整型指针来接收是不行的. (4) void test(int* arr[5]) {}不行! 形参写成了数组,数组的每个元素是int*,完全搭不上 二维数组传参,要么写成二维数组的形式,要么写成指针的形式,这里写的是指针数组显然是不对的 (5) void test(int(*arr)[5]) {}ok 二维数组首元素的地址是一维数组首元素的地址,要用5个整型的数组指针来接收 (6) 形参的部分可以写成二级指针的形式吗? void test(int **arr) {}因为传过去的就不是一个一级指针,二级指针是用来接收一级指针的地址 这个写法完全不对,传过去的是一行的地址拿二级指针接收,完全不搭配 结论: 二维数组传参,参数可以是指针,也可以是数组. 如果是数组,行可以省略,但列不能省略 如果是指针,传过去的事第一行的地址,形参就应该是数组指针 3.一级指针传参 指针在传参的时候,类型只要匹配上,没有任何问题 一级指针传过去,形参的部分用一级指针接收 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,10 };int* p arr; //1的地址交给了pint sz sizeof(arr) / sizeof(arr[0]);//一级指针p,传给函数print(p, sz);return 0; }思考: 当一个函数的形参部分为整型的一级指针的时候,函数能接收什么参数? (1)传一个整型变量的地址 int a; print(a,10);(2)传一个整型指针 int a; int *p1a; print(p1,10);(3)传整型数组的数组名 int arr[10]; print(arr,10);4.二级指针传参 二级指针传参的时候,形参部分就用二级指针接收 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; }pp二级指针传参的时候,形参的部分直接写成二级指针就可以了 p是二级指针的地址,传过去应该用二级指针变量接收 思考: 当函数的参数是二级指针的时候,可以接收什么参数? 比如: 当只有下面这个函数的时候,调用它的时候可以传什么? void test(int** ptr) {printf(num%d\n, **ptr); }(1)传一个二级指针变量 (2)传一个一级指针变量的地址 (3)传一个指针数组 因为数组名表示首元素的地址,数组的每个元素都是int*,首元素的地址就是int*的地址,也就是二级指针,这里用二级指针接收,没问题 int* arr[10]; test(arr);五、函数指针 1.回顾一下指针的类型 整型指针-指向整型的指针 int* 字符指针-指向字符的指针 char* 数组指针-指向数组的指针 int arr[10]; int (*p)[10]arr; 函数指针-指向函数的指针 数组指针中存放的是数组的地址 函数指针中存放的是函数的地址 函数名 得到的就是函数的地址 数组: 数组名:首元素的地址 数组名:数组的地址 函数: 函数名和函数名,都是函数的地址,没有区别 int Add(int x, int y) {return x y; } int main() {printf(%p\n, Add);printf(%p\n, Add);return 0; }2.函数指针变量用来存放函数的地址 pf是函数指针的名字,去掉它是函数指针的类型,不需要交代形参的名字 int Add(int x, int y) {return x y; } int main() {int (*pf)(int,int) Add;//pf是函数指针的名字,去掉它是函数指针的类型,不需要交代形参的名字return 0; }3.通过函数指针调用它指向的函数 int Add(int x, int y) {return x y; } int main() {int (*pf)(int,int) Add;//pf是函数指针的名字,去掉它是函数指针的类型,不需要交代形参的名字int ret (*pf)(3, 5); //调用printf(%d\n, ret);return 0; }pf是函数指针的名字,去掉它是函数指针的类型.把Add放到pf里边,Add和pf就是一回事 总结: (1)函数指针调用: int ret (*pf)(3, 5); 在看完下面的(2)(3)之后发现这里的*其实就是一个摆设,那为什么既然是一个摆设,还能用呢? 其实就是为了方便理解,通常来说,pf是一个指针,要访问指针指向的对象需要解引用一下找到这个函数,然后再去调用它.对于编译器来说写或者不写都无关紧要.多写几个也无所谓,不会影响. 但是如果写的话,一定要把它和函数指针变量括起来,然后找到那个函数再调用它. (2) 曾经调用函数使用:拿到函数名就是函数地址,再传参就可以调用,把结果放到ret里边去 int retAdd(3,5);(3)同理,Add和pf一回事,写成下面的形式也可以: int retpf(3,5);上述知识考察 下面这个函数的地址怎么用函数指针存起来? char* test(int c,float* pf){}解答: int main() { char* (*pf)(int,float*)test; return 0; }4.阅读两段有趣的代码 下面的代码是什么意思呢? 代码1 int main() {(*(void(*)())0)();return 0;}(1) 从0开始找切入口,0前面的括号里面是void( * )(),void( * )()是函数指针的类型. (2) 类型放到括号里面是什么意思?是要进行强制类型转换. 0本来是int类型的,在前面放一个括号意思是强制类型转换,也就是把0转换成一种指针类型(在这里是函数指针类型),0也就转换成了函数地址 (4) 前面有一个*,也就是对强转换的地址进行解引用----调用这个函数,调用的时候要传参,所以在最后有一个圆括号,调用的时候没有传参 代码1的意思: I.将0强制类型转成void(*)()类型的函数指针 II.这就意味着0地址处放着一个函数,函数没有参数,返回类型是void III.调用0地址处的这个函数 代码2: int main() {void(*signal(int, void(*)(int)))(int);return 0; }理解: 函数的名字是signal,第一个参数是int类型,第二个参数是函数指针类型,去掉signal(int, void()(int)),剩下的void( )(int)即函数的返回类型是函数指针 代码2的意思: 上面的代码是一个函数声明 函数的名字是signal 函数的参数第一个是int类型,第二个类型是void(*)(int)类型的函数指针 该函数指针指向的函数参数是int,返回类型是void signal函数的返回类型也是一个函数指针,该函数指针指向的函数参数是int,返回类型是void 代码2不易于理解,用typedef简化一下 typedef可以把某些类型进行简化 typedef int* ptr_t; //将int*取别名为ptr_t //将void(*)(int)类型的函数指针重新起个别名叫pf_t //写成typedef void(*)(int) pf_t是不符合语法的,重命名必须放在*的旁边 typedef void(*pf_t)(int); pf_t signal(int, pf_t);注意: typedef void(*pf_t2)(int); //pf_t2是类型名 void(*pf)(int); //pf是函数指针变量的名字一般对类型重定义用typedef,不用#define 六.函数指针数组 指针数组:整型指针的数组 函数指针数组:数组的每个元素是一个函数指针 int Add(int x,int y) {return x y; } int Sub(int x, int y) {return x - y; } int Mul(int x, int y) {return x * y; } int Div(int x, int y) {return x / y; }int main() {//同样类型的变量要定义四次非常繁琐,用数组统一保存int(*pf1)(int, int) Add;int(*pf2)(int, int) Sub;int(*pf3)(int, int) Mul;int(*pf4)(int, int) Div;//存放函数指针的数组---函数指针数组int(*pf[4])(int, int) {Add,Sub,Mul,Div};//数组里面存放四个元素,每个元素是函数指针类型的数据,存的是四个函数的地址//下标:0 1 2 3//找到这四个函数int i 0;for (i 0; i 4; i) {int ret pf[i](8, 4); //pf[i]代表的是数组里面各个元素,再传参,用ret接收结果printf(%d\n, ret);}return 0; }知识点练习 写一个计算器能完成整数的±*/ void menu() {printf(***************************************\n);printf(******1.add 2.sub**********************\n);printf(******3.mul 4.div**********************\n);printf(******0.exit **********************\n);printf(***************************************\n);} int Add(int x, int y) {return x y; } int Sub(int x, int y) {return x - y; } int Mul(int x, int y) {return x * y; } int Div(int x, int y) {return x / y; }int main() {int input 0;int x 0;int y 0;int ret 0;do {menu();printf(请选择-);scanf(%d, input);//只有输入1234的时候才需要打印结果//为了避免无关紧要的一些结果的输出switch (input) {case 1:printf(请输入两个操作数:);scanf(%d %d, x, y);ret Add(x, y);printf(%d\n, ret);break;case 2:printf(请输入两个操作数:);scanf(%d %d, x, y);ret Sub(x, y);printf(%d\n, ret);break;case 3:printf(请输入两个操作数:);scanf(%d %d, x, y);ret Mul(x, y);printf(%d\n, ret);break;case 4:printf(请输入两个操作数:);scanf(%d %d, x, y);ret Div(x, y);printf(%d\n, ret);break;case 0:printf(退出计算器\n);break;default:printf(选择错误\n);break;} }while (input);return 0; }在计算机基础上, 增加一些其他的功能: | ^ || 一直case下去代码太长了,有没有简化的方法? 将上面的代码简化 void menu() {printf(***************************************\n);printf(******1.add 2.sub**********************\n);printf(******3.mul 4.div**********************\n);printf(******0.exit **********************\n);printf(***************************************\n);} int Add(int x, int y) {return x y; } int Sub(int x, int y) {return x - y; } int Mul(int x, int y) {return x * y; } int Div(int x, int y) {return x / y; }int main() {int input 0;int x 0;int y 0;int ret 0;//转移表//先输入一个下标,通过下标找到对应的函数,然后调用这个函数//有一种跳转的效果//注意:放进指针数组的函数的指针类型要保持一致//NULL就是0,0就是NULL,这里起到的是占位的作用int (*pfArr[])(int, int) {NULL,Add,Sub,Mul,Div}; //创建一个函数指针的数组//下标 0 1 2 3 4do {menu();printf(请选择-);scanf(%d, input);if (input 1 input 4) { //这里的4可以写成sizeof(pfArr)/sizeof(pfArr[0]再-1)printf(请输入两个操作数:);scanf(%d %d, x, y);ret pfArr[input](x, y); //pfArr[i]找到的是数组里面元素的地址,找到之后传参数x,y,调用函数printf(%d\n, ret);}else if (input 0) {printf(退出计算器\n);break;}else {printf(选择错误\n);}} while (input);return 0; }注意点: 总结 指针进阶的上部分内容就到这里啦,如果对友友们有帮助的话,记得点赞收藏博客,关注后续的指针进阶下集内容哦~
http://www.w-s-a.com/news/175382/

相关文章:

  • 做网站网课阿里云域名查询系统
  • saas建站平台有哪些简述网站建设基本流程答案
  • 个人怎么做网站网站浏览思路
  • 网站建设里的知识长沙网络营销公司
  • 网站建设与维护大作业pc网站转换成微网站
  • php网站开发经典教材东莞网站开发
  • 教育培训手机网站模板下载跨境电商培训哪家最好
  • 网站开发淄博网站被降权会发生什么影响吗
  • 网站开发常用的语言东城手机网站制作
  • 微小店网站建设平台手机优化加速有什么用
  • 沈阳酒店企业网站制作公司竞价网站怎么做seo
  • 中山企业网站多少钱学网站建设的好处
  • 做官网网站哪家公司好jianux wordpress
  • 插件素材网站新站seo优化快速上排名
  • 网站注销主体填写原因asp响应式h5网站源码下载
  • 电商类网站模板下载济南市建设网官网
  • 万户网络做网站如何采集器wordpress
  • 襄阳网站建设企业查看 wordpress 插件
  • 网站地址申请京东联盟怎么做网站
  • 三亚市城乡建设局网站网站口碑营销
  • 图书租借网站 开发企业网站搜索优化外
  • 新乡个人网站建设哪家好免费的图片做视频在线观看网站
  • 洛阳工程建设信息网站山西响应式网页建设哪里好
  • 企业网站建设市场的另一面wordpress分类插件
  • 网站建设名头公司展厅装修
  • 小型购物网站开发费用郑州企业网站模板建站
  • 个体商户建自己的网站做销售建设积分兑换官方网站
  • 网站建设与维护培训网页制作专业用语
  • 建站特别慢wordpress网页制作与设计项目策划书
  • 视频制作素材免费网站头像制作在线生成器