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

ipv6改造 网站怎么做6seo短视频网页入口引流免费

ipv6改造 网站怎么做6,seo短视频网页入口引流免费,python做网站性能,镇江做网站多少钱目录 1. 指针的运算 2. 野指针和悬空指针 2.1 野指针 2.2 悬空指针 3. void类型指针 4. 二级指针和多级指针 4.1 命名规则 4.2 作用 4.2.1 二级指针可以操作一级指针记录的地址 4.2.2 利用二级指针获取变量中记录的数据 1. 指针的运算 文章开始前可以先了…

目录

1.  指针的运算

2.  野指针和悬空指针

2.1  野指针

2.2  悬空指针

3.  void类型指针

4.  二级指针和多级指针

4.1  命名规则

4.2  作用

4.2.1  二级指针可以操作一级指针记录的地址

4.2.2  利用二级指针获取变量中记录的数据


1.  指针的运算

文章开始前可以先了解:C语言指针·入门用法超详解-CSDN博客

        通过上一章我们初步了解了指针的用法,知道指针的类型是:

        其中指针中数据类型的作用是获取字节数据的个数,正常情况下变量p只能获取到0x001的内存地址,而int型数据占4字节,因此:

        那么我们可以思考一下,若是:

int a=10;
int* p=&a;p+1

        假设a的地址为:0x01,那么p+1指向的地址会是什么呢?

        会是0x02还是0x05呢?

        正确答案应该是:0x05,这是为什么呢?

步长:指针移动一次的字节个数

        因为,指针的加法操作实际上是将指针向后移动若干个存储单元,而不是简单的数学加法,上面我们也提到了正常情况下变量p只能获取到0x01的内存地址,而int型数据占4字节,而p+1就是指针移动一步,一步在这里是四个字节,因此p+1,最终会移动到0x05的位置。我们拿代码验证一下:

#include <stdio.h>int main()
{/** 指针的运算* 步长:指针移动一次,走了多少字节* char:1* short:2* int:4* long:4* long long:8*///加法:指针往后移动了N步P+N//减法:指针往前移动了N步P-Nint a = 10;int* p = &a;printf("%p\n", p);printf("%p\n", p + 1);printf("%p\n", p + 2);printf("%p\n", p - 1);printf("%p\n", p - 2);return 0;
}


注意:

指针有意义的操作:

        指针跟整数进行加、减操作(每次移动N个步长)

        指针跟指针进行减操作(间隔步长)

#include <stdio.h>int main()
{/** 有意义的操作:指针跟整数进行加、减操作(每次移动N个步长)指针跟指针进行减操作(间隔步长)无意义的操作:指针跟整数进行乘除操作原因:此时指针指向不明指针跟指针进行加、乘、除操作*///前提条件:保证内存空间是连续的//数组int arr[] = { 1,2,3,4,5,6,7,8,9 };//获取0索引的内存地址int* p1 = &arr[0];//指针跟整数进行加、减操作(每次移动N个步长)//通过内存地址获取数据printf("%d\n", *p1);printf("%d\n", *(p1 + 1));//获取5索引的内存地址int* p2 = &arr[5];//p2 - p1间隔了多少步长printf("%d\n", p2 - p1);printf("%p\n", p1);printf("%p\n", p2);return 0;
}

指针无意义的操作:

        指针跟整数进行乘除操作

        原因:此时指针指向不明

        指针跟指针进行加、乘、除操作


2.  野指针和悬空指针

2.1  野指针

        野指针:指针指向的空间未分配。

#include <stdio.h>int main()
{/*野指针:指针指向的空间未分配悬空指针:指针指向的空间已分配,但是被释放了*///野指针:指针指向的空间未分配int a = 10;int* p1 = &a;printf("%p\n", p1);printf("%d\n", *p1);//p2为野指针int* p2 = p1 + 10;printf("%p\n", p2);printf("%d\n", *p2);return 0;
}

        此时运行程序,虽然也能得到p2的地址,但是要知道,这块地址我们并没有给他分配,他虽然能找到地址,但是若是随意修改数据,在正常使用中,可能会修改别的函数的数据,导致最终运行错误: 

2.2  悬空指针

        悬空指针:指针指向的空间已分配,但是被释放了。

#include <stdio.h>int* method();int main()
{/*野指针:指针指向的空间未分配悬空指针:指针指向的空间已分配,但是被释放了*///悬空指针:指针指向的空间已分配,但是被释放了int* p3 = method();printf("拖点时间\n");printf("拖点时间\n");printf("拖点时间\n");printf("拖点时间\n");printf("拖点时间\n");printf("拖点时间\n");printf("%p\n", p3);printf("%d\n", *p3);return 0;
}int* method()
{int num = 10;int* p = &num;return p;
}

        会发现此时代码数据错误,正常p3应当显示10: 

        这里可以调用static来使用:

#include <stdio.h>int* method();int main()
{/*野指针:指针指向的空间未分配悬空指针:指针指向的空间已分配,但是被释放了*///悬空指针:指针指向的空间已分配,但是被释放了int* p3 = method();printf("拖点时间\n");printf("拖点时间\n");printf("拖点时间\n");printf("拖点时间\n");printf("拖点时间\n");printf("拖点时间\n");printf("%p\n", p3);printf("%d\n", *p3);return 0;
}int* method()
{static int num = 10;int* p = &num;return p;
}

3.  void类型指针

特殊类型:void* p

不表示任何类型,只能记录地址值,不能获取到变量里面的数据,也不能进行加减的计算。

特点:无法获取数据,无法计算,但是可以接收任意地址数据。

        在我们使用指针的过程中会发现,不同类型的指针之间是不能相互赋值的,否则会发生编辑错误:

#include <stdio.h>int main()
{//void类型指针//定义两个变量int a = 10;short b = 20;//定义两个指针int* p1 = &a;short* p2 = &b;//输出打印printf("%d\n", *p1);printf("%d\n", *p2);//不同类型的指针之间是不能相互赋值的char* p3 = p1;printf("%d\n", *p3);//这里编译器为我们进行了强制类型转换,上面的过程相当于如下char* p4 = (char*)p1;printf("%d\n", *p4);return 0;
}

         这里的指针间进行复制那是因为编译器在编译过程中,对p1进行了强制类型转换,p3的实际流程,如p4所示:

        为了解决这一问题我们可以将数据类型定义为void,不过这也会导致,不能printf输出数据,因为void不能获取到变量里面的数据,也不能进行加减的计算,否则编译器会报错:

#include <stdio.h>int main()
{//void类型指针//定义两个变量int a = 10;short b = 20;//定义两个指针int* p1 = &a;short* p2 = &b;//输出打印printf("%d\n", *p1);printf("%d\n", *p2);//不同类型的指针之间是不能相互赋值的char* p3 = p1;printf("%d\n", *p3);//这里编译器为我们进行了强制类型转换,上面的过程相当于如下char* p4 = (char*)p1;printf("%d\n", *p4);//void类型指针打破上面的观念//void没有任何类型,好处可以接收任意类型指针记录内存地址void* p5 = p1;void* p6 = p2;//缺点:不能获取到变量里面的数据,也不能进行加减的计算//printf("%d\n", *p5);//printf("%d\n", *p6);//printf("%d\n", *p5 - 1);//printf("%d\n", *p6 + 1);return 0;
}

        那么我们引用void有什么用呢?

        例如,我们用于调用函数进行交换数据,我们可以编写如下代码:

#include <stdio.h>void swap(void* p1, void* p2);int main()
{//void类型指针//定义两个变量int a = 10;short b = 20;//定义两个指针int* p1 = &a;short* p2 = &b;//输出打印printf("%d\n", *p1);printf("%d\n", *p2);//不同类型的指针之间是不能相互赋值的char* p3 = p1;printf("%d\n", *p3);//这里编译器为我们进行了强制类型转换,上面的过程相当于如下char* p4 = (char*)p1;printf("%d\n", *p4);//void类型指针打破上面的观念//void没有任何类型,好处可以接收任意类型指针记录内存地址void* p5 = p1;void* p6 = p2;//缺点:不能获取到变量里面的数据,也不能进行加减的计算//printf("%d\n", *p5);//printf("%d\n", *p6);//printf("%d\n", *p5 - 1);//printf("%d\n", *p6 + 1);//调用函数交换数据int c = 100;int d = 200;swap(&c, &d);printf("c=%d,d=%d\n", c, d);return 0;
}//函数:用来交换两个变量记录数据void swap(int* p1, int* p2)
{int temp = *p1;*p1 = *p2;*p2 = temp;
}

         此时可以实现数据的交换:

        但是若是此时我想使用long long型数据呢?数据会发生报错(我在DevC++上运行报错,在VS上运行正确,因为VS在这里编辑器给他自动强制类型转换了):

#include <stdio.h>void swap(void* p1, void* p2);int main()
{//void类型指针//定义两个变量int a = 10;short b = 20;//定义两个指针int* p1 = &a;short* p2 = &b;//输出打印printf("%d\n", *p1);printf("%d\n", *p2);//不同类型的指针之间是不能相互赋值的char* p3 = p1;printf("%d\n", *p3);//这里编译器为我们进行了强制类型转换,上面的过程相当于如下char* p4 = (char*)p1;printf("%d\n", *p4);//void类型指针打破上面的观念//void没有任何类型,好处可以接收任意类型指针记录内存地址void* p5 = p1;void* p6 = p2;//缺点:不能获取到变量里面的数据,也不能进行加减的计算//printf("%d\n", *p5);//printf("%d\n", *p6);//printf("%d\n", *p5 - 1);//printf("%d\n", *p6 + 1);//调用函数交换数据long long c = 100L;long long d = 200L;swap(&c, &d);printf("c=%lld,d=%lld\n", c, d);return 0;
}//函数:用来交换两个变量记录数据void swap(int* p1, int* p2)
{int temp = *p1;*p1 = *p2;*p2 = temp;
}

        那么我们如何才能进行不同类型都能调用该函数呢?可以使用void类型,

void swap(void* p1, void* p2)
{int temp = *p1;*p1 = *p2;*p2 = temp;
}

        但是如果使用void又会出现新的问题就是:void不能获取到变量里面的数据,也不能进行加减的计算,那么要如何解决呢?

           这里将void*类型的指针p1和p2分别转换为char*类型的指针pc1和pc2。这是因为char类型是 C 语言中的基本数据类型,且大小为1字节,所以可以通过char*指针逐字节访问内存。     

        同时函数void swap(void* p1, void* p2, int len)加上一个len用于表示字节数,要是int型len就等于4,long long就是等于8(在x64环境下):

void swap(void* p1, void* p2, int len)
{//把void类型的指针,转换char类型的指针char* pc1 = p1;char* pc2 = p2;char temp = 0;//以字节为单位,一个字节一个字节的进行转换for (int i = 0; i < len; i++){temp = *pc1;*pc1 = *pc2;*pc2 = temp;pc1++;pc2++;}
}

        完整程序代码: 

#include <stdio.h>void swap(void* p1, void* p2, int len);int main()
{//void类型指针//定义两个变量int a = 10;short b = 20;//定义两个指针int* p1 = &a;short* p2 = &b;//输出打印printf("%d\n", *p1);printf("%d\n", *p2);//不同类型的指针之间是不能相互赋值的char* p3 = p1;printf("%d\n", *p3);//这里编译器为我们进行了强制类型转换,上面的过程相当于如下char* p4 = (char*)p1;printf("%d\n", *p4);//void类型指针打破上面的观念//void没有任何类型,好处可以接收任意类型指针记录内存地址void* p5 = p1;void* p6 = p2;//缺点:不能获取到变量里面的数据,也不能进行加减的计算//printf("%d\n", *p5);//printf("%d\n", *p6);//printf("%d\n", *p5 - 1);//printf("%d\n", *p6 + 1);//调用函数交换数据int c = 100;int d = 200;swap(&c, &d, 4);printf("c=%d,d=%d\n", c, d);return 0;
}//函数:用来交换两个变量记录数据
/*
void swap(int* p1, int* p2)
{int temp = *p1;*p1 = *p2;*p2 = temp;
}
*///修改一下函数,更具有通用性
//因为以上函数,若是主函数调用的话,只能int类型的数据
void swap(void* p1, void* p2, int len)
{//把void类型的指针,转换char类型的指针char* pc1 = p1;char* pc2 = p2;char temp = 0;//以字节为单位,一个字节一个字节的进行转换for (int i = 0; i < len; i++){temp = *pc1;*pc1 = *pc2;*pc2 = temp;pc1++;pc2++;}
}

4.  二级指针和多级指针

4.1  命名规则

        以二级指针为例,上一章最初我们了解了什么是指针?

C语言指针·入门用法超详解-CSDN博客

         那么既然普通变量就有指针,指针也是一个变量为什么不能有一个指针继续指向他呢?那么我们可以了解到:

        既然指针也有他的指针,那么指针的指针要怎么命名呢?

        其和指针的命名规则是一样的也是:

数据类型  *  变量名;

        但是需要注意的是:指针的数据类型要跟指向空间中的数据的类型保持一致。

        首先对于指针p,其指向数据a的地址,需要和a数据类型保持一致,那么指针的命名就是:

int                       *                    p;

数据类型           标记            变量名

        然后,二级指针指向的是指针的数据类型,此时指针空间内存储的不是数据,而是a的地址,他的数据类型是int*,也就是说二级指针的命名:

int*                       *                    p;

数据类型           标记            变量名

4.2  作用

4.2.1  二级指针可以操作一级指针记录的地址

        上代码:

#include <stdio.h>int main()
{//定义变量int a = 10;int b = 20;//定义一级指针int* p = &a;printf("a的地址:%p\n", &a);printf("b的地址:%p\n", &b);printf("修改前p的地址:%p\n", p);//定义二级指针int** pp = &p;*pp = &b;printf("修改后p的地址:%p\n", p);return 0;
}

        可以发现p的地址被修改了,简单点来说:初始时,p指向变量a的地址。然后,通过pp这个二级指针,修改了p的指向,使其指向了变量b的地址。因此,最后输出显示p的地址发生了变化,从指向a的地址变为指向b的地址。

4.2.2  利用二级指针获取变量中记录的数据

#include <stdio.h>int main()
{//定义变量int a = 10;int b = 20;//定义一级指针int* p = &a;//定义二级指针int** pp = &p;printf("修改前获取变量里面的数据:%d\n", **pp);*pp = &b;printf("修改后获取变量里面的数据:%d\n", **pp);return 0;
}

C语言指针·入门用法超详解-CSDN博客

指针_时光の尘的博客-CSDN博客

http://www.wangmingla.cn/news/10612.html

相关文章:

  • wordpress栏目链接地址福州seo经理招聘
  • 做伊瑞尔竞技场的网站优化关键词规则
  • 网站建设需求模板下载交换友情链接的渠道
  • 衢州建筑地基加固哪家好网站专业术语中seo意思是
  • wordpress留言板comments.php添加自定义字段威海seo公司
  • 苏州保洁公司诗雨常德seo公司
  • 建设通招标网站上海知名网站制作公司
  • 策划案需要给做网站吗福州百度seo排名软件
  • 开展我国电子网站建设营销云
  • 网站做的一样算不算侵权seo推广方法有哪些
  • 做网站的条件网站设计与制作公司
  • 网站建设台州广告网络推广怎么做
  • 分销网站建立下载百度2023最新版
  • 如何在电脑上建立网站销售网站排名
  • 网站制作模板下载网址查询注册信息查询
  • 武汉网站建设价格seo在线培训机构
  • 网站怎么做网络推广深圳高端网站建设公司
  • 6黄页网站建设营销型网站
  • 个人做网站郊游的英外贸推广哪个公司好
  • 集合视频网站资源怎么做游戏优化是什么意思
  • 网页设计与制作大全seo快速上排名
  • 网站开发的可行性报告快速排名优化推广价格
  • 武汉移动网站制作推广什么软件可以长期赚钱
  • 搭建公司网站多少钱新软件推广
  • 营销网店推广的软文百度优化排名软件
  • 九江有哪些免费推广网站开鲁网站seo转接
  • 交易服务型b2b电子商务网站百度企业推广
  • 上海公司做网站的网络优化工程师前景如何
  • 网站建设技术参数网站优化排名易下拉排名
  • 成都网站建设招聘企业查询官网入口