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

织梦安装网站后图片全屋定制设计流程

织梦安装网站后图片,全屋定制设计流程,做网站订金为什么需要交那么多,泰安有什么互联网公司文章目录 1.指针的定义2.指针的加减运算3.野指针4.指针 数组 传参 字符数组5.数组指针 指针数组6.二级指针7.指针函数 函数指针 回调函数8.函数指针数组 指向函数指针数组的指针 1.指针的定义 指针是内存中一个最小单元的编号… 文章目录 1.指针的定义2.指针的加减运算3.野指针4.指针 数组 传参 字符数组5.数组指针 指针数组6.二级指针7.指针函数 函数指针 回调函数8.函数指针数组 指向函数指针数组的指针 1.指针的定义 指针是内存中一个最小单元的编号也就是地址。平常口语中所说的指针通常指的是指针变量是用来存放内存地址的变量。指针的大小在32位平台是4个字节在64位平台是8个字节。可以通过sizeof求得指针的大小。 #include stdio.hint main() {int a 5;char c a;int* ptra a;char* ptrc c; printf(%ld\n,sizeof(ptra));printf(%ld\n,sizeof(ptrc));return 0; }我的系统64位的Ubuntu系统所以输出8。从上面的代码可以看出用 type * 定义一个指针变量而取地址 可以取得变量的地址。另外输出ptra和ptrc的结果都一样难道它们的类型一样。不是的ptra的类型是int*用来接收int类型变量的地址而ptrc的类型是char*用来接收char类型变量的地址。对指针赋值的时候类型要匹配 可以定义指针那么如何取出指针的指向的内容呢其实它和定义指针用的是同一个操作符 * 解引用操作符或间接访问操作符指针的类型决定了对指针解引用的时候有多大的权限能操作几个字节char* 指针的解引用就只能访问1个字节int*指针的解引用就只能访问4个字节。 #include stdio.hint main() {int a 5;int* ptra a;printf(%d\n,*ptra);return 0; }2.指针的加减运算 C语言程序运行指针的整数加减但是不能乘除其实加减有时候就够头疼了要是能乘除那不得了了指针的加减会根据指针的类型决定了指针向前或者向后走一步有多大距离这时候能直观体现指针是有类型的。 #include stdio.hint main() {int a 5;char c a;int* ptra a;char* ptrc c; printf(prta : before %p : after %p\n,ptra,ptra 1);printf(prtc : before %p : after %p\n,ptrc,ptrc 1);return 0; }输出结果输出的结果是按照16进制来展示的。 prta : before 0x7ffca65b0c74 : after 0x7ffca65b0c78 prtc : before 0x7ffca65b0c73 : after 0x7ffca65b0c743.野指针 指针是很灵活的但是有时候灵活就代表着容易出错如果对指针操作不当那么很容易造成野指针。所谓的野指针就是指针指向的位置是不可知的随机的、不正确的、没有明确限制的。 1、比如我对int* 类型的指针加一然后解引用访问就会出错指针越界访问int 只有4个字节大小的空间属于它 通常越界访问是对数组经行操作所以要注意数组下标访问是否越界。 int main() {int a 5;int* ptra a;printf(*prta : before %d : after %d\n,*ptra,*(ptra 1));return 0; }输出有些环境就程序直接就崩溃了这里就输出了随机值。 *prta : before 5 : after 17475926522、指针未初始化 int main() {int* ptra;printf(*prta : before %d : after %d\n,*ptra,*(ptra 1));return 0; }3、指针指向的空间释放。对malloc动态申请的内存free后再去访问也会造成野指针。 如何避免野指针的出现 1.指针初始化、2.小心指针越界、3.指针指向空间释放即使置NULL、4.避免返回局部变量的地址、5.指针使用之前检查有效性。 上面的方法都是依靠程序员有良好的编码习惯而人有时候会犯错所以在C中引入了智能指针来避免野指针。 4.指针 数组 传参 字符数组 数组名首元素的地址它和数组名输出的结果是一样但是它们代表并不是一个意思因为指针是有类型的。 int main(int argc,char* argv[]) {int arr[5] {1,2,3,4,5};printf(%p\n,arr);printf(%p\n,arr);return 0; }输入结果 0x7ffebf362450 0x7ffebf362450如果对数组名 1和数组名 1会发现它们输出的内容是不一样的。 int main(int argc,char* argv[]) {int arr[5] {1,2,3,4,5};printf(%p\n,arr);printf(%p\n,arr);printf(%p\n,arr 1);printf(%p\n,arr 1);return 0; }输出结果 0x7ffd97b8f650 0x7ffd97b8f650 0x7ffd97b8f654 0x7ffd97b8f664指针的类型决定了指针向前或者向后走一步有多大距离。数组名 1会跳过4个字节因为它的类型是 int*而数组名 1的类型是int (*)[5] 整形数组指针跳过了20个字节。如果尝试这样赋值 int * p arr编译器会提醒你 test.c:374:15: warning: initialization of ‘int *’ from incompatible pointer type ‘int (*)[5]’ [-Wincompatible-pointer-types]374 | int * p arr;如果自动一个函数想要接收一个整形数组不需要定义数组指针只需要传递首元素的地址就能访问到整个数组的元素。可以有三种方式。 方式一 void get(int* arr){}方式二这种方式需要和传入的数组的大小匹配比较的麻烦现实中定义函数的人也知道要定义多大。如果可以在函数中打印一下arr发现就是一个指针的大小而不是将整个数组传递。 void get(int arr[5]) {printf(%ld\n,sizeof(arr)); }方式三直接用方式一就好了。 void get(int arr[]){}C语言没有像其他语言一样提供好用的String类型来处理字符串它是通过char *指向 引起的字符串常量或者通过字符数组栈再或者存放到malloc开辟的动态内存空间中。不管怎么说以\0标志结尾的C风格的字符串挺难用的。 那么char * 字符指针和字符数组处理字符有什么区别呢 int main() {const char* str1 hello world;const char* str2 hello world;char str3[] hello world;char str4[] hello world;printf(str1 %p : str2 %p\n,str1,str2);printf(str3 %p : str4 %p\n,str3,str4);return 0; }输出结果 str1 0x55a2615af008 : str2 0x55a2615af008 str3 0x7fff95f06ca0 : str4 0x7fff95f06cacstr1 和 str2 指向了存放在常量区中的同一个hello world字符串的首元素的地址而str3 和str4在栈区开辟了两块不同的内存存放Hello world。这样做虽然浪费了一定的内存但是字符数组中存放的内容可以修改而char* 指向的字符串常量不能被修改通常会加上一个const来修饰。另外从键盘上输入字符就需要用到字符数组来接收。 int main() {char str1[] {h,e,l,l,o};char str2[] {h,e,l,l,o,\0};char str3[] hello;printf(%ld\n,sizeof(str1));printf(%ld\n,sizeof(str2));printf(%ld\n,sizeof(str3));printf(%zd\n,strlen(str1));printf(%zd\n,strlen(str2));return 0 }这里str1 定义并不是字符串因为C字符串要以\0结尾所以strlen输出什么都是未定义的。这里注意区分sizeof 是计算内存的大小而strlen是计算字符串的长度。 5.数组指针 指针数组 数组指针是指针而指针数组是数组用来存放指针。它们的定义非常的相似。 数组指针 int (*p1)[5]p1是一个指针变量指向的是一个大小为5个整型的数组。 指针数组 int *p2[5]p2是数组名可以存放着5个int * 类型的指针。 这里定义数组指针需要括号因为 [] 的优先级要高于 *号的加上来保证p1先和*结合。使用指针数组可以接收一维数组名。也可以接收二维数组中的元素注意二维数组中的元素是一维数组的地址。 void show(int(*p)[5],int cow,int col) {for (int i 0;i cow ; i) {for (int j 0; j col; j) {printf(%d ,p[i][j]);}printf(\n);} }int main() {int a[2][5] {{1,2,3,4,5},{6,7,8,9,10}};show(a,2,5);return 0; }上面show函数打印了二维数组的值数组通过 [] 访问更加清晰一些。在C中通过重载 [] 也让容器在逻辑上顺序访问哪怕它的底层空间不是连续的。这里的[] 和 * 是等价的。也可以用下面的方式访问到二维数组的元素。 printf(%d ,*(*p i) j); printf(%d ,*((*(p i)) j));再来看一看指针数组。来定义一个指针数组并打印这些值。 int main(int argc,char* argv[]) {char* names[5] {张三,李四,王五,赵六,田七};for(int i 0;i 5;i){printf(%s\n,names[i]);}return 0; }上面的例子似乎没有什么挑战那如果从键盘上输入五个人的名字并输出呢怎么做。就有一个关键点指针数组中存放的是指针如果从键盘上输入要用字符数组然后赋值给指针。 int main(int argc,char* argv[]) {char* names[5]; for(int i 0; i 5;i){char name[25] {0};printf(请输入一个名字:);scanf(%s,name);names[i] name;}for(int i 0;i 5;i){printf(%s\n,names[i]);}return 0; }我们来使用指针数组完成一个有意思的东西学过Linux的同学知道cat 命令是查看文本中的内容。我们自己编写一个程序也实现cat 命令完成的任务。没学过Linux也没有关系知道了怎么编写命令学的时候就不会被它唬住。 #include stdio.h #include string.h #include stdlib.hint main(int argc,const char* argv[]) {if(argc 1){printf(Usage: %s file1 [file2 ...]\n,argv[0]);return -1;}for(int i 1;i argc;i){FILE* file fopen(argv[i],r);if(file NULL){perror(文件不存在!\n);return -1;}char ch;while((ch fgetc(file)) ! EOF){fputc(ch,stdout);}fclose(file);}return 0; }通过gcc编译并添加到环境变量中 ☁ day2024_11_14 [master] ⚡ gcc test.c[自己的文件名] -o easy_cat ☁ day2024_11_14 [master] ⚡ sudo mv easy_cat /usr/bin ☁ day2024_11_14 [master] ⚡ easy_cat test.c6.二级指针 指针变量也是变量存放指针变量的指针称为二级指针。 int main() {int num 5;int *p num;int **pp p;printf( pp : %p p : %p\n, pp,p);printf(**pp : %d *p : %d\n,**pp,*p);return 0; }输出结果 pp : 0x7fff341ddbc8 p : 0x7fff341ddbc8 **pp : 5 *p : 5那么二级指针的用处是什么呢。函数的传参的方式有传值和传地址着两种方式传值传递参数是指的拷贝如果想改变两个变量的地址那么就需要通过指针传递。同样的道理我想改变指针变量的内容就需要指针变量的地址那就是二级指针。 交换两个int 变量的值 void swap(int* a,int* b) {int tmp *a;*a *b;*b tmp; }int main() {int a 5;int b 10;printf(before a %d,b %d\n,a,b);swap(a,b);printf(after a %d,b %d\n,a,b); }交换两个int* 指针变量指向的值 void swap(char** a,char** b) {char* tmp *a;*a *b;*b tmp; }当你想改变指针变量的指向的时候可以考虑使用二级指针很多的数据结构中二级指针都是很常见的。另外在巩固一下如果要编写一个函数打印指针数组的值改怎么做呢。 void showName(char** names,int size) {for(int i 0;i size;i){printf(%s ,names[i]);}printf(\n); }int main() {char* names[5] {张三,李四,王五,赵六,田七};showName(names,5);return 0; }为什么需要二级指针接收呢可以这么理解names[0] 类型为char* 而names[0]的类型为char**。数组名就是首元素的地址name names[0]实参传递的是 char**类型showName的形参类型也要用二级指针来接收。 7.指针函数 函数指针 回调函数 函数返回值类型是指针的函数称为指针函数通常是返回堆空间的指针避免返回栈上空间出了作用域被销毁访问一块销毁的空间。 void* malloc(int size); char* strcpy(char* dest,char* src);函数指针的本质是指针用来存放函数的地址而函数名就是函数在内存中首元素的地址。如何判断函数的类型。如定义一个add函数 int add(int a,int b)确认一个函数类型最快速的方法是去掉函数名和函数的形参就是函数的类型。add 函数的类型是int (int,int)。然后添加一个 (* p)就可以定义一个函数指针了。 #include stdio.hint add(int a,int b) {return a b; }int main() {int (*p1)(int,int) add;int (*p2)(int,int);p2 add;printf(%d\n,p1(1,2));printf(%d\n,p2(1,3));return 0; }定义的函数指针可以在定义的时候赋初值也可以先声明在赋值。使用函数指针像函数一样使用即可。既然像函数一样使用那干嘛要麻烦的定义函数指针呢定义函数指针可以让函数以参数的方式传递让声明和实现分离提高了代码的模块化程度。 这就像其他如Java语言中定义接口通过接口来调用实现接口的类。 下面实现了加减如果发生乘除取模整除等添加另外的功能函数的类型一样都可以通过calculate去调用。 #include stdio.hint add(int a,int b) {return a b; }int sub(int a,int b) {return a - b; }int calculate(int cal(int,int),int a,int b) {return cal(a,b); }int main() {printf(%d\n,calculate(add,5,10));printf(%d\n,calculate(sub,10,5));return 0; }回调函数callback通常我们调用别人的函数API这个过程叫做call而别人在他定义的函数中调用我们的函数这个行为就是callback。上面的例子中calculate 调用cal 这个动作就是callback。在C语言中qsort 就用到了callback 。 #include stdio.h #include stdlib.hint int_cmp(const void* p1,const void* p2) {return *(int*)p1 - *(int*)p2; }int main() {int arr[] {1,6,2,3,8,9,3};int size sizeof(arr) / sizeof(arr[0]);qsort(arr,size,sizeof(int),int_cmp);for(int i 0;i size;i){printf(%d ,arr[i]);}printf(\n);return 0; }那qsort大概是怎么实现的呢使用一个冒泡排序实现对任意类型数据的排序。 C语言中使用void* 来接收任意类型但是void* 不能加减运算但是类型又是不确定的所以只能转成最小类型的指针char* 按照一个字节来操作数据。比较的时候只需要两个确定元素的地址而char* 一次只能跳过一个字节所以要根据size来确定跳几个字节。交换的时候是按照一个一个字节交换内容要交换size次。 void _swap(void* p1,void* p2,int size) {for(int i 0;i size;i){char ch *((char*)p1 i);*((char*)p1 i) *((char*)p2 i);*((char*)p2 i) ch;} }void my_qsort (void* base, size_t num, size_t size,int (*compar)(const void*,const void*)) {for(int i 0; i num - 1;i){for(int j 0;j num -1 -i;j){if(compar((char*)base j * size,(char*)base (j 1) * size) 0){ _swap((char*)base (j* size),((char*)base (j 1)* size),size);}}} }int int_cmp(const void* p1,const void* p2) {return *(int*)p1 - *(int*)p2; }int main() {int arr[] {5,1,2,3,8,9,3};int size sizeof(arr) / sizeof(arr[0]);my_qsort(arr,size,sizeof(int),int_cmp);for(int i 0;i size;i){printf(%d ,arr[i]);}printf(\n);return 0; }8.函数指针数组 指向函数指针数组的指针 用来存放函数指针的数组。在上面的calculate例子中可以使用函数指针数组来存放函数指针。 int add(int a,int b) {return a b; }int sub(int a,int b) {return a - b; }int main() {int (*p[2])(int,int) {add,sub};for(int i 0;i 2;i){printf(%d\n,p[i](10,5));} }当然还可以定义一个指向函数指针数组的指针 int (*(*pp)[2])(int,int) p;
http://www.dnsts.com.cn/news/182793.html

相关文章:

  • win2012 iis 部署网站wordpress支付查看插件
  • 三水网站建设企业如何制作游戏
  • 手机能建网站不帝国做的电影网站
  • 南昌网站搭建服务唐山做网站
  • 一个综合网站上线多少钱网络营销的原理
  • 电子商务网站建设与管理思考与练习大兴模版网站建设公司
  • 网站排名优化平台深圳华强北二手手机市场
  • 高端的响应式网站建设公司大德通众包做网站怎么样
  • 建立了公司网站王也电脑壁纸
  • 免费行情软件网站有哪些网站构建是什么
  • 集团网站建设哪家好做第三方团购的平台网站
  • 网站建设公司有哪些主要内容组成网站做项目
  • 响应式企业展示型网站wordpress用户站内信
  • 学生做义工网站东营考试信息网官网2020
  • 青海网站建设加q5299丶14602做词织梦汽车网站模板
  • 服装设计网站哪个好网页设计html代码大全图片
  • 分享一个网站能用的哈佛门户网站建设特点
  • 唐山的网站建设wordpress本地搬家到服务器
  • 网站模版好建设吗宣传片拍摄方案怎么写
  • 论坛网站开发成本网站编程工具
  • 网站有没有做301如何使用网站模板建设网站
  • 建设电影会员网站个人网站注册
  • 做网站遇上麻烦客如何让新网站被收录
  • 网站建设项目软件开发招标文件江门网站建设方案
  • ssh框架做音乐网站wordpress页面如何排序
  • ps做网站页面美工百度风云榜游戏
  • 广东建设基金管理有限公司网站网站建设行业市场规模
  • 反腐网站建设的目的哇塞fm网站维护
  • 科讯cms 网站地图app推广引流
  • 建立自己的摄影网站重庆网站建设安全