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

制作钓鱼网站seo是什么东西

制作钓鱼网站,seo是什么东西,WordPress底部添加版权注明,株洲网站建设服务平台目录 一、指针概述 指针的定义 指针的大小 指针的解引用 野指针 指针未初始化 指针越界访问 指针运算 二级指针 指针与数组 二、字符指针 三、指针数组 四、数组指针 函数指针 函数指针数组 指向函数指针数组的指针 回调函数 指针与数组 一维数组 字符数组…

目录

一、指针概述

指针的定义

指针的大小

指针的解引用

野指针

指针未初始化

指针越界访问

指针运算

二级指针

指针与数组

二、字符指针

三、指针数组

四、数组指针

函数指针

函数指针数组

指向函数指针数组的指针

回调函数

指针与数组

一维数组

字符数组

二维数组


一、指针概述

指针的定义

数据是存放在内存中的,每一个内存空间都会有一个像房间号一样的编号,比如某某五星级酒店3109号房间,只有获得了这个编号才能找到这个房间,这个编号就是地址。而指针就是用来存放这个地址的变量。总结来说:指针是一个变量,是用来存放内存地址的变量,我们通常称谓指针变量。

指针的大小

是由计算机的物理性质决定的,一般的计算机分为32位机和64位机,32位机就是由32根地址线组成,每一根地址线都会传递高电平(1)或者低电平(0)。那么32根地址线就会产生2^32次方个地址,所以64位机的地址以此类推。8bite = 1字节——32位机的地址就由4个字节存储,62位机的地址就由8个字节的地址存储。

指针类型:数据的存储方式有 char、short、int、long、long long、float、double、struct、void
因此对应反指针类型也就有:char*、short*、int*、long*、long long*、float*、double*、struct*、void*

int main()
{//什么类型数据的地址就得放到对应类型的指针变量中char ch = 'w';char* pc = &ch;int num = 10;int* p = #return 0;
}

指针的解引用

指针的类型决定了,对指针解引用的时候有多大的权限(能取到多大的字节数)。比如: char* 的指针解引用就只能访问一个字节,而 int* 的指针的解引用就能访问四个字节。

野指针

指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)

指针未初始化

int main()
{ //局部变量指针未初始化,默认为随机值int *p;//没有指向对应的地址空间,无法查找地址*p = 20;return 0;
}

指针越界访问

int main()
{int arr[10] = {0};int *p = arr;for(int i=0; i<=11; i++){//当指针指向的范围超出数组arr的范围时,p就是野指针*(p++) = i;}return 0;
}

指针指向的空间释放,在堆里开辟内存的空间,如果被回收就不能在使用,因此指针就不能再指向那块空间的地址。

指针运算

指针的类型决定 + - 整数,指针变量所偏移的空间大小

int main()
{float arr[5];//指针+-整数;指针的关系运算for (float *p = &arr[0]; vp < &arr[5];){//后置++,先给数组赋值在偏移四个字节*p++ = 0;}return 0;}

指针 - 指针

//模拟实现strlen
int my_strlen(char *s)
{char *p = s;while(*p != '\0' )p++;return p-s;//两个指针之间的空间个数
}

指针的关系运算,允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与指向第一个元素之前的那个内存位置的指针进行比较。

#define N_VALUES 5
int main()
{float values[N_VALUES];float *vp;//不能让数组第一个元素的地址与数组第一个元素之前的地址进行比较for(vp = &values[N_VALUES-1]; vp >= &values[0];vp--){*vp = 0;}return 0;
}

二级指针

指针变量也是一个变量,每一个变量都会存放到内存中,也就会有地址。二级指针,就是用来存放一级指针变量地址的变量。因此,存放一级指针变量地址的指针为二级指针,存放二级指针变量地址的指针为三级指针,以此类推。

 

指针与数组

可见数组名和数组首元素的地址是相同的。 因为数组是一块连续的空间,所以可以用指针指向数组首元素的地址,通过指针的加减来访问数组的每一个空间。

arr可以理解为一个变量,即一个内存空间。

二、字符指针

将字符变量的地址放到字符指针中称为字符指针。一种比较特殊的字符指针指向的是常量池中字符串首字符的地址,常量池当中的字符串是不能修改的。而将字符串放到数组当中进行存储的值是可以修改的。

char a = ‘w’;char* pa = &a;char* p = "abcdef";

备注:const加在*前表示不能修改指针所指向空间的值,const加在*后表示不能修改指针的指向

字符串数组和常量字符串的区别:

int main()
{//用相同的常量字符串去初始化不同的数组的时候就会开辟出不同的内存块//str1,str2字符串数组存放的是对应字符的asc码值//值虽然相同但是他们是两个不同数组,开辟的地址也是不同的char str1[] = "hello bit.";char str2[] = "hello bit.";//字符指针str3,str4存放的是字符串常量池的字符,存放的都是字符'h'的地址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;
}

三、指针数组

整型数组 - 存放整型的数组
字符数组 - 存放字符的数组
指针数组 - 存放指针(地址)的数组
指针数组是存放指针的数组,每种类型的数据都可以创建数组,但是数组也可以是由指针组成。

存放字符指针的数组

参数pc是是一个二级指针,存储的是abcdef字符串的地址,每次挪1字节

存放数组首地址的指针数组

四、数组指针

字符指针——存放字符地址的指针——指向字符的指针 char*
整型指针——存放整型地址的指针——指向整型的指针 int*
浮点型的指针——存放浮点型地址的指针——指向浮点型的指针 float*  double*
数组指针——存放数组地址的指针——指向数组的指针

数组名和&数组名的区别:

数组指针的使用,使用一:两种打印数组的方式

数组指针的使用,使用二:二维数组的使用

//正常的接受二维数组的参数
void print1(int arr[3][4], int r, int c)
{int i = 0;for (i = 0; i < r; i++){int j = 0;for (j = 0; j < c; j++){printf("%d ", arr[i][j]);}printf("\n");}
}//用数组指针来接受二维数组,表示的是数组的第几行
void print2(int(*p)[4], int r, int c)
{int i = 0;for (i = 0; i < r; i++){int j = 0;for (j = 0; j < c; j++){			//printf("%d ", (*(p + i))[j]);printf("%d ", p[i][j]);}printf("\n");}
}int main()
{int arr[3][4] = { {1,2,3,4}, {2,3,4,5} , {3,4,5,6} };print1(arr, 3, 4);printf("\n");//数组名arr,表示首元素的地址//但是二维数组的首元素是二维数组的第一行//所以这里传递的arr,其实相当于第一行的地址,是一维数组的地址//可以数组指针来接收print2(arr, 3, 4);return 0;
}

 

函数指针

函数指针的定义与使用

类型名  (*指针变量名)(函数参数)  = &函数名(或者直接写函数名)
//函数指针
int Add(int x, int y)
{return x + y;
}int main()
{//pf 是一个存放函数地址的指针变量 -  函数指针int (*pf)(int, int) = &Add;//可以理解为&Add给pfint ret = (*pf)(2,3);//&函数名和函数名都是函数的地址int (*pf)(int, int) = Add;//int ret = Add(2, 3);int ret = pf(2, 3);printf("%d\n", ret);return 0;
}

函数名也可以理解为一个指针变量,指针变量就是一块内存,内存中记录一个地址;变量也是一块内存直接记录值。*a取a的值,&a取a的低地址,a标识一块内存。

函数指针数组

函数指针数组的定义

数组是一个存放相同类型数据的存储空间,前面有讲到指针数组,那要把函数的地址存到一个数组中,那这个数组就叫函数指针数组。

                    数据类型 ( * 数组名[数值] ) (函数参数);
如:

int ( * parr1 [ 10 ])();
int * parr2 [ 10 ]();

函数指针数组的使用(转移表)

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 (*pf[5])(int, int) = { NULL, Add, Sub, Mul, Div };int main()
{int input = 0;int x = 0;int y = 0;int ret = 0;do{menu();printf("请选择:>");scanf("%d", &input);if (input == 0){printf("退出计算器\n");break;}else if (input>=1 &&input<=4){printf("请输入两个操作数:>");scanf("%d %d", &x, &y);ret = pf[input](x, y);printf("%d\n", ret);}else{printf("选择错误\n");}} while (input);return 0;
}

指向函数指针数组的指针

指向函数指针数组的指针是一个 指针指向一个数组, 数组的元素都是 函数指针 

void test(const char* str)
{printf("%s\n", str);
}
int main()
{//函数指针pfunvoid (*pfun)(const char*) = test;//函数指针的数组pfunArrvoid (*pfunArr[5])(const char* str);pfunArr[0] = test;//指向函数指针数组pfunArr的指针ppfunArrvoid (*(*ppfunArr)[5])(const char*) = &pfunArr;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;
}void calc(int (*pf)(int, int))
{int x = 0;int y = 0;int ret = 0;printf("请输入两个操作数:>");scanf("%d %d", &x, &y);ret = pf(x, y);printf("%d\n", ret);
}int main()
{int input = 0;do {menu();printf("请选择:>");scanf("%d", &input);switch (input){case 1:calc(Add);break;case 2:calc(Sub);break;case 3:calc(Mul);break;case 4:calc(Div);break;case 0:printf("退出计算器\n");break;default:printf("选择错误\n");break;}} while (input);return 0;
}

指针与数组

一维数组

int main()
{//一维数组int a[] = { 1,2,3,4 };//4*4=16printf("%d\n", sizeof(a));//16printf("%d\n", sizeof(a + 0));//a+0 其实是数组第一个元素的地址,是地址就是4/8字节printf("%d\n", sizeof(*a));//*a是数组首元素,计算的是数组首元素的大小,单位是字节,4printf("%d\n", sizeof(a + 1));//a+1是第二个元素的地址,是地址大小就是4/8printf("%d\n", sizeof(a[1]));//a[1]是第二个元素,计算的是第二个元素的大小-4-单位是字节printf("%d\n", sizeof(&a));//&a是整个数组的地址,整个数组的地址也是地址,地址的大小就是4/8字节//&a---> 类型:int(*)[4]printf("%d\n", sizeof(*&a));//&a是数组的地址,*&a就是拿到了数组,*&a--> a,a就是数组名,sizeof(*&a)-->sizeof(a)//计算的是整个数组的大小,单位是字节-16printf("%d\n", sizeof(&a + 1));//&a是整个数组的地址,&a+1,跳过整个数组,指向数组后边的空间,是一个地址,大小是4/8字节printf("%d\n", sizeof(&a[0]));//&a[0]是首元素的地址,计算的是首元素地址的大小,4/8字节printf("%d\n", sizeof(&a[0] + 1));//&a[0] + 1是第二个元素的地址,地址的大小就是4/8字节return 0;
}

字符数组

int main()
{//字符数组char arr[] = { 'a','b','c','d','e','f' };//char*//char [6]printf("%d\n", strlen(arr));//随机值printf("%d\n", strlen(arr + 0));//随机值//printf("%d\n", strlen(*arr));//strlen('a')->strlen(97),非法访问-err//printf("%d\n", strlen(arr[1]));//'b'-98,和上面的代码类似,是非法访问 - errprintf("%d\n", strlen(&arr));//&arr虽然是数组的地址,但是也是从数组起始位置开始的,计算的还是随机值//char(*)[6]printf("%d\n", strlen(&arr + 1));//&arr是数组的地址,&arr+1是跳过整个数组的地址,求字符串长度也是随机值printf("%d\n", strlen(&arr[0] + 1));//&arr[0] + 1是第二个元素的地址,是'b'的地址,求字符串长度也是随机值printf("%d\n", sizeof(arr));//arr单独放在sizeof内部,计算的是整个数组的大小,单位是字节,6printf("%d\n", sizeof(arr + 0));//arr + 0是数组首元素的地址,4/8printf("%d\n", sizeof(*arr));//*arr是数组的首元素,计算的是首元素的大小-1字节printf("%d\n", sizeof(arr[1]));//arr[1]是第二个元素,大小1字节printf("%d\n", sizeof(&arr));//取出的数组的地址,数组的地址也是地址,是地址大小就是4/8printf("%d\n", sizeof(&arr + 1));//&arr+1是跳过整个,指向数组后边空间的地址,4/8printf("%d\n", sizeof(&arr[0] + 1));//&arr[0] + 1是数组第二个元素的地址,是地址4/8字节return 0;
}

int main()
{char arr[] = "abcdef";//数组是7个元素//[a b c d e f \0]printf("%d\n", strlen(arr));//6,arr是数组首元素的地址,strlen从首元素的地址开始统计\0之前出现的字符个数,是6printf("%d\n", strlen(arr + 0));//arr + 0是数组首元素的地址,同第一个,结果是6printf("%d\n", strlen(*arr));//*arr是'a',是97,传给strlen是一个非法的地址,造成非法访问printf("%d\n", strlen(arr[1]));//errprintf("%d\n", strlen(&arr));//6printf("%d\n", strlen(&arr + 1));//&arr + 1是跳过数组后的地址,统计字符串的长度是随机值printf("%d\n", strlen(&arr[0] + 1));//&arr[0]+1是b的地址,从第二个字符往后统计字符串的长度,大小是5printf("%d\n", sizeof(arr));//7 - 数组名单独放在sizeof内部,计算的是数组的总大小,单位是字节printf("%d\n", sizeof(arr + 0));//arr+0是首元素的地址,大小是4/8printf("%d\n", sizeof(*arr));//*arr是数组首元素,大小是1字节printf("%d\n", sizeof(arr[1]));//arr[1]是数组的第二个元素,大小是1字节printf("%d\n", sizeof(&arr));//&arr是数组的地址,数组的地址也是地址,是4/8字节printf("%d\n", sizeof(&arr + 1));//&arr + 1是跳过整个数组的地址,是4/8字节printf("%d\n", sizeof(&arr[0] + 1));//&arr[0] + 1是第二个元素的地址,是4/8字节return 0;
}

int main()
{const char* p = "abcdef";printf("%d\n", strlen(p));//6- 求字符串长度printf("%d\n", strlen(p + 1));//p + 1是b的地址,求字符串长度就是5printf("%d\n", strlen(*p));//err,*p是'a'printf("%d\n", strlen(p[0]));//err - 同上一个printf("%d\n", strlen(&p));//&p拿到的是p这个指针变量的起始地址,从这里开始求字符串长度完全是随机值printf("%d\n", strlen(&p + 1));//&p+1是跳过p变量的地址,从这里开始求字符串长度也是随机值printf("%d\n", strlen(&p[0] + 1));//&p[0] + 1是b的地址,从b的地址向后数字符串的长度是5printf("%d\n", sizeof(p));//p是指针变量,大小就是4/8字节printf("%d\n", sizeof(p + 1));//p + 1是b的地址,是地址,就是4/8个字节printf("%d\n", sizeof(*p));//*p是'a',sizeof(*p)计算的是字符的大小,是1字节printf("%d\n", sizeof(p[0]));//p[0]-->*(p+0) --> *p  就同上一个,1字节printf("%d\n", sizeof(&p));//&p是二级指针,是指针大小就是4/8printf("%d\n", sizeof(&p + 1)); //&p + 1是跳过p变量后的地址,4/8字节printf("%d\n", sizeof(&p[0] + 1));//p[0]就是‘a’,&p[0]就是a的地址,+1,就是b的地址,是地址就是4/8return 0;
}

 

二维数组

int main()
{//二维数组int a[3][4] = { 0 };//printf("%p\n", &a[0][0]);//printf("%p\n", a[0]+1);printf("%d\n", sizeof(a));//48 = 3*4*4printf("%d\n", sizeof(a[0][0]));//4printf("%d\n", sizeof(a[0]));//a[0]是第一行的数组名,数组名单独放在sizeof内部,计算的就是数组(第一行)的大小,16个字节printf("%d\n", sizeof(a[0] + 1));//a[0]作为第一行的数组名,没有单独放在sizeof内部,没有取地址,表示的就是数组首元素的地址//那就是a[0][0]的地址,a[0]+1就是第一行第二个元素的地址,是地址就是4/8个字节printf("%d\n", sizeof(*(a[0] + 1)));//*(a[0] + 1)是第一行第2个元素,计算的是元素的大小-4个字节printf("%d\n", sizeof(a + 1));//a是二维数组的数组名,数组名表示首元素的地址,就是第一行的地址,a+1就是第二行的地址//第二行的地址也是地址,是地址就是4/8   //a - int (*)[4]//a+1--> int(*)[4]printf("%d\n", sizeof(*(a + 1)));//a+1是第二行的地址,*(a+1)表示的就是第二行,*(a+1)--a[1]  //16printf("%d\n", sizeof(&a[0] + 1));//&a[0]是第一行的地址,&a[0]+1是第二行的地址,地址的大小就是4/8printf("%d\n", sizeof(*(&a[0] + 1)));//*(&a[0] + 1) 是对第二行的地址解引用,得到的就是第二行,计算的就是第二行的大小printf("%d\n", sizeof(*a));//a表示首元素的地址,就是第一行的地址,*a就是第一行,计算的就是第一行的大小//*a -- *(a+0)--a[0]printf("%d\n", sizeof(a[3]));//16字节 int[4]//如果数组存在第四行,a[3]就是第四行的数组名,数组名单独放在sizeof内部,计算的是第四行的大小int a = 10;printf("%d\n", sizeof(int));return 0;
}

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

相关文章:

  • wordpress文章批量编辑网站优化方案模板
  • 北京互联网公司开发的网站今日关注
  • 网站限制上传图片大小免费网络推广100种方法
  • 提供网站建设服务的网站价格快速推广
  • 政府网站建设原则 统筹规划进入百度官网
  • 网站如何做等级保护谷歌搜索引擎363
  • 天河网站建设网络推广不属于网络推广方法
  • 阜阳中国建设银行官网站百度提交入口网站网址
  • 游戏网站怎么建设广告营销公司
  • 韩城做网站b2b平台推广网站
  • 网站建设课程设计摘要生活中的网络营销有哪些
  • 简单网站建设优化推广100个电商平台
  • 网站建设的仿站seo顾问收费
  • 珠宝行业做网站的好处株洲seo排名
  • java web开发网站开发cpa推广接单平台
  • 广西南宁网络营销网站网站权重优化
  • 黄山网站设计公司营销网站建设多少钱
  • 网站建设招标评分表湖南关键词优化推荐
  • 淘宝上成都网站建设如何制作视频网站
  • 最吃香的男生十大手艺5g网络优化
  • 河源哪里做网站网络项目怎么推广
  • 网站闭关保护怎么做广州百度seo 网站推广
  • 可以在线做动图的网站近期重大新闻事件
  • 伊犁州建设局网站怎么做微信小程序
  • 做网站需要买主机那新媒体营销方式有几种
  • 网络推广seo公司seo排名的方法
  • 南山做网站多少钱百度资讯
  • 西安哪里有做网站的小学生收集的新闻10条
  • 做游戏网站有几个要素seo网站关键词优化报价
  • 蓬业东莞网站建设技术支持东莞做网站公司首选