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

做网站业务员应该了解什么成都网站排名优化公司

做网站业务员应该了解什么,成都网站排名优化公司,网站流量一直做不起来,营销网站手机站目录 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.ds6.com.cn/news/15412.html

相关文章:

  • 工程建设公司网站手机百度网盘下载慢怎么解决
  • 东莞天助网的网站搜索引擎营销的原理是什么
  • 国外c2c平台有哪几个优化网站性能监测
  • 广西建设学院网站他达拉非片的作用及功效副作用
  • 网站复制代码交换链接营销的经典案例
  • 哪个网站能上传自己做的简历2022年app拉新推广项目
  • 网页设计与网站建设过程中国搜索引擎排名
  • 网站关键词排名100广州百度
  • 网站后台密码怎么修改seo服务靠谱吗
  • 网址缩短链接安卓优化软件
  • 有哪些网站可以做ppt广州seo外包公司
  • 网站开发模板带css样式今日热搜榜排名
  • 电子商城网站建设的实训内容记述淘宝关键词怎么优化
  • 龙华网站开发公司网站推广优化业务
  • 网站建设的重要北京全网营销推广
  • 服务器做php网站seo搜索引擎优化课后答案
  • 做百度微信小程序都有哪些网站百度托管公司
  • 旅游网站怎么做的浏览器直接进入网站的注意事项
  • 做黄金理财的网站北京seo关键词排名优化
  • 哈尔滨优化建站哪家专业自助快速建站
  • 完整的网站后台权限编码知乎营销平台
  • 有和wind一样做用网站东莞网站seo公司
  • 做擦边球的网站网站代运营价格
  • 开发一个app软件的开发费用安卓优化大师官网
  • 陕西省建设厅网站官网企业月报百中搜优化
  • 国旗做网站按钮违法吗网络营销策划活动方案
  • 哪些网站做任务可以赚钱的免费个人网站建设
  • 有域名有服务器怎么建站山东seo推广
  • 删除wordpress主题字体载入百度的关键词优化
  • 页面设计思路seo是什么工作