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

上海企业网站建设靠谱数据分析平台

上海企业网站建设靠谱,数据分析平台,群晖做网站,wordpress和ecshop整合前言 今天来较为深入的介绍一下指针,希望大家能有所收获~ 那么,先进行一些简单的基础知识复习吧。 字符指针 格式:char * 补充: 表达式“abcdef”的值是首字符a的地址 所以当像下面这么使用时,它的含…

前言

今天来较为深入的介绍一下指针,希望大家能有所收获~

那么,先进行一些简单的基础知识复习吧。
在这里插入图片描述

字符指针

格式:char *

补充:

表达式“abcdef”的值是首字符a的地址
所以当像下面这么使用时,它的含义是:

char *pc = “abcde”

pc存储的是a的地址

printf(%s”, p)

打印出的abcde

提示:

此处可以理解为将abcde存储在一个数组里面,数组名就是首元素地址

那么由此可以引出一个比较少见的写法:


输出的是c

注意

因为字符串“abcde”是常量,不可改变,但是,p作为指针变量是可以改变的,这时候改变p指向的对象程序就会报错。

所以最后在*左边加上const,使p指向的对象不可改变

一道题:

看下面这段代码:
问:输出结果是什么

#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("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;
}

运行结果:

在这里插入图片描述

知识点:
当两个常量数组相同时,只会储存一份,
所以,虽然创建了两个变量,但存储的是同一个地址(同一个值)

图解:
在这里插入图片描述

指针数组

定义:存放指针的数组

用途:
可以用指针数组模拟一个二维数组

如下:

int main()
{int arr1[] = { 1,2,3,4,5 };int arr2[] = { 2,3,4,5,6 };int arr3[] = { 3,4,5,6,7 };int* arr[] = { arr1, arr2, arr3 };int i = 0;return 0;
}

数组指针

定义:指向数组的指针
格式(唯一):
存储元素的类型 (*p)[数组大小] = &arr

注意:要明确指定出数组的大小,如果不写就默认为0,程序会报错。

但数组指针的使用不常见,
因为当对数组指针进行解引用后,就是数组名,多此一举。
就算使用,也大多用于二维数组,下面举个例子

void print(int (*p)[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 ", p[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;
}

此处数组名指向的是二维数组的第一行
这里传递的 arr,也就是第一行的地址,是一维数组的地址
此处用数组指针来接收。

旧识新知

数组名指的是首元素的地址,
但有两个例外
1.sizeof(数组名)此处指的是整个数组

2.&数组名
取出的是数组的地址

那么创建一个变量存储数组的地址,他就是数组的指针,简称数组指针

但是 此处需要注意区分数组名和取地址数组名,虽然在打印时二者是一样的,但在运算时,因为 &arr 表示的是 数组的地址 ,所以它是以整个数组大小去运算的,而不是数组中首元素的大小

示例如下:

#include <stdio.h>
int main()
{int arr[10] = { 0 };printf("arr = %p\n", arr);printf("&arr= %p\n", &arr);printf("arr+1 = %p\n", arr+1);printf("&arr+1= %p\n", &arr+1);return 0;
}

运行结果:
在这里插入图片描述
这样就能直观的看出二者的区别

一组辨析

大家可以思考一下下面几行的代码的含义是什么

int arr[5];
int *parr1[10];
int (*parr2)[10];
int (*parr3[10])[5];

解释:
在这里插入图片描述
在这里插入图片描述

数组传参和指针传参

接下来,我会为大家介绍三种传参情况
一维数组传参、二维数组传参、一级指针传参、二级指针传参

一维数组传参

看看下面这段代码,思考一下那种传参方式是可行的。

#include <stdio.h>
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);
}

答案是:这些写法都可以。

数组传参传的是数组首元素的地址。

二维数组传参

我们先看这段代码:

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 <stdio.h>
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 };int* p = arr;int sz = sizeof(arr) / sizeof(arr[0]);//一级指针p,传给函数print(p, sz);return 0;
}

用一级指针来实现打印数组。
一级指针传参,形参也要写成一级指针的形式来接收。

思考:

当一个函数的参数部分为一级指针的时候,函数能接收什么参数?

有如下三种方式:
在这里插入图片描述
传入数组名(数组首元素的地址)
传入整型变量的地址
传入一级指针

二级指针传参

#include <stdio.h>
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;
}

同样,二级指针传参要用同样是二级指针的形参来接收

思考;

当函数的参数为二级指针的时候,可以接收什么参数?

有如下三种方式:
在这里插入图片描述

传进去一级指针的地址
传进去二级指针
传进去指针数组的首元素地址(也就是指针的地址)

函数指针

定义:指向函数的指针,在内存空间中存放的是函数的地址。

函数地址:&函数名
或者 直接写函数名
函数名就是函数的地址

代码示例:

#include <stdio.h>
void test()
{printf("hehe\n");
}
int main()
{printf("%p\n", test);printf("%p\n", &test);return 0;
}

程序输出的结果相同。

函数指针的存储

观察下面这段代码,看看那个才是函数指针

void test()
{printf("hehe\n");
}
//下面pfun1和pfun2哪个有能力存放test函数的地址?
void (*pfun1)();
void *pfun2();

答案:第一个
因为pfun1先与8结合,是一个指针,然后才指向这个函数。
这个函数不传参,并且返回类型为void

格式:
指针的类型 (*pf)(函数参数的类型) = 函数名

运用:

想通过函数指针来实现两个数的求和,可以怎么写呢?

代码如下;

int Add(int x, int y)
{return x + y;
}
int main()
{int (* pf2)(int, int) = &Add;//这里需要把类型强转换成整型int ret = (* pf2)(2, 3);printf("%d\n", ret);return 0;
}

所以函数调用可以写成:
pf(参数)

*个数随便写,但要用括号括起来,

(*pf)(参数)

提示:

在使用函数指针时,是不用写*的,因为pf本就是地址,想要调用函数,直接解引用就行,不用多写星号,并且此处写多少个星号都行,
写星号只是为了提醒其他人这个变量是函数指针,便于理解。

题目:

下面介绍两段有趣的代码,大家可以思考一下他们的含义是什么

1.

(*(void (*)())0)();

拆开来看:
void(*)()是一个函数指针类型,

对(void (*)())0,就是强制类型转换0,把0转换成可以接收函数地址的指针变量,

那么0地址处就有void(*)()这么一个函数,
所以这段代码的意思就是:调用0地址处的函数,这个函数没有参数,返回类型是void。

2.

void (*signal(int , void(*)(int)))(int);

这行代码我们从里往外看

图解如下:
在这里插入图片描述

可以通过使用typedef,简化成两行代码:

typedef void(*pfun_t)(int);
pfun_t signal(int, pfun_t);

结语

指针的知识暂时介绍到这里,下篇文章会继续介绍关于指针的知识,比如函数指针数组、指向函数指针数组的指针、回调函数等,我们下次见。

http://www.hkea.cn/news/2241/

相关文章:

  • 网站建设虚线的代码对网站和网页的认识
  • 网站案例欣赏建网站seo
  • 好用的做微信公众号的网站今日最新国内新闻
  • 日本wordpress模板下载地址seo优化网站查询
  • 网站滚动效果怎么做的seo软件哪个好
  • windowxp做网站服务器百度竞价推广账户优化
  • 网站建设图片怎么做百度seo怎么样优化
  • 郑州做网站哪家公司最好2023年8月疫情爆发
  • 网站建设维护管理软件互联网平台推广怎么做
  • .net 网站开发流程新榜数据平台
  • 杭州网站建设制作公司广州seo网络推广员
  • flash网站源代码百度网盘app下载安装
  • 华夏望子成龙网站开发背景免费创建网站平台
  • 什么网站有项目做吸引人的推广标题
  • 网站模版建设工具南昌seo数据监控
  • 企业网站 制作百度推广管理平台
  • 平台不得诱导下载一个具体网站的seo优化
  • 国外做节目包装的网站百度客户端下载
  • 北京市办理居住卡在哪个网站做crm系统
  • 学校做网站难吗哪个好用?
  • 营销网站建设一薇网络整合营销方案
  • 动态网站开发工程师证免费seo
  • 相册网站怎么做的品牌网络推广怎么做
  • wordpress cnd加速郑州专业seo首选
  • 网页设计面试自我介绍长沙有实力seo优化
  • 做视频网站用什么好处世界新闻最新消息
  • 顺德高端网站设计seo是什么东西
  • layui 网站建设模板百度网址链接是多少
  • 娄底网站建设的话术网站建设是什么
  • 有没有免费的crm系统武汉百度搜索优化