C/C++指针之提高篇详解(二) 您所在的位置:网站首页 古埃及人介绍大全 C/C++指针之提高篇详解(二)

C/C++指针之提高篇详解(二)

2022-11-30 08:16| 来源: 网络整理| 查看: 265

一、引言

C/C++语言中引入了指针,使得程序能够直接访问内存地址,使得很多复杂的操作变得简单,同时也提高了程序的运行效率。指针即是地址,但是地址却是通过指针变量来存储的。这就好比我们的教室,每个教室都有一个房间号,一个房间号也对应着一间教室,此处的教室就是固定的地址(指针),其地址是通过房间号(指针变量)来表示的。地址就是指针,而房间号就是指针变量。 笔者在《C/C++指针入门详解(一)》一文中给出了指针的基础知识和基本用法。详见链接: https://blog.csdn.net/sunnyoldman001/article/details/128061186?spm=1001.2014.3001.5502 本文给出了有关指针的更多应用场景及示例,例如函数指针、文件指针、更换数据类型、双指针等等。

二、指针的应用

1.根据需要改变内存中数据的数据类型 例1:在位域中,经常会根据需要把某单一变量存储到内存中,然后根据需要将其转换为结构体类型,进而可以进行一些复杂的操作,例如提取某个或某几个比特位上的数据等。 示例代码:

#include"stdio.h" struct weiyu { unsigned char a:5; unsigned char b:2; unsigned char c:4; }; int main() { weiyu *p; unsigned short val = 1521;//10111110001 //将存储变量a的地址赋值给指针变量p,并将内存中的数据类型改换为结构体 p = (struct weiyu*)&val; printf("weiyu a = %d\n", p->a); printf("weiyu b = %d\n", p->b); printf("weiyu c = %d\n", p->c); return 0; }

运行结果: 在这里插入图片描述 说明: 本例中将低比特位0 ~ 4上的“10001”赋值为结构体成员a,因此a的值是17,将比特位5 ~ 6上的“11”赋值为结构体成员b,因此b的值是3,将比特位8 ~ 11上的“101”赋值为结构体成员c,因此c的值是5。比特位7上的“1”被舍弃。 2.文件指针 例2:打开某一文本文本,向屏幕输出该文件内容,并统计字符‘e’出现的次数。 参考代码:

#include "stdio.h" #include "stdlib.h" int main() { FILE *fp;//文件指针 char ch; int count = 0; //打开文件,并用文件指针fp指向文件的首地址 if( ( fp = fopen("file.cpp", "rt" ) ) == NULL ) { printf("Cannot open file!"); exit(1); } ch = fgetc(fp);//从文件中读取一个字符 while( ch != EOF ) { putchar(ch);//向屏幕输出读到的字符 if( ch == 'e' ) { count++; } ch = fgetc(fp); } fclose(fp);//关闭文件 printf( "\n字母e出现的次数:%d\n", count ); return 0; }

运行结果: 在这里插入图片描述 3.双指针 指针可以用来实现函数的双向传值功能,其原理类似于在把指针作为地址(可以看成是一个教室),地址里的内容可以根据需要进行修改(教室里的学生可以更换),以实现双向传值的功能。但是地址本身是不可以更改的(你不能把教室搬家)。但是有些时候还真就是希望可以把地址搬家,那么怎么办呢?其实可以利用双指针来实现,也就是把地址放入新的地址中,类似于在一个教学楼里,在房间号已经固定的情况下,为了满足某一种需要,而重新给教室分配房间号一样,如果把教室看成地址的话,那么教学楼就是一个二级地址,用来存储教室。当把教学楼作为地址单函数参数的话,那么该地址中的内容就可以根据需要随意修改了,这其实就是双指针。 例3:利用函数参数的形式交换两个指针的地址 参考代码:

#include"stdio.h" #include"malloc.h" void swap( int **p,int **q ); int main() { int a, b, **p, **q; //首先给p和q分配空间,存储的是地址的地址 p = (int **)malloc( sizeof(int) ); q = (int **)malloc( sizeof(int) ); a = 1; b = 2; *p = &a; *q = &b; printf( "交换前地址:p: %x, q: %x\n", *p, *q ); printf( "交换前的数据:p: %d, q: %d\n", **p, **q ); swap( p, q ); printf( "交换后地址:p: %x, q: %x\n", *p, *q ); printf( "交换后的数据:p: %d, q: %d\n", **p, **q ); return 0; } //将p和q所指向地址中存储的地址进行交换 void swap( int **p,int **q ) { int *temp; temp = *p; *p = *q; *q = temp; }

运行结果: 在这里插入图片描述 说明:此用法比较复杂,在双指针被使用前必须要初始化。用时要慎重!!! 4.函数指针 C语言中的函数指针是指向函数的指针变量。用法类似于C++的模板。 定义函数指针的一般形式为:

类型说明符 (*函数名)(形参表) ;

此函数仅仅是一个声明,无函数体。此处的“函数名”严格来说只是一个指针,它指向了某个函数的入口地址。 例4:利用函数指针实现求两个整数的最大值、最小值、和。 参考的代码:

#include"stdio.h" int max( int a, int b ); int min( int a, int b ); int sum( int a, int b ); int (*f)(int a, int b); int main() { int a = 1, b = 2; f = max; int c = (*f)( a, b ); printf( "%2d 和 %2d 的最大值: %2d\n", a, b, c ); f = min; c = (*f)( a, b ); printf( "%2d 和 %2d 的最小值: %2d\n", a, b, c ); f = sum; c = (*f)( a, b ); printf( "%2d 和 %2d 的和: %2d\n", a, b, c ); return 0; } int max( int a, int b ) { return a > b ? a : b; } int min( int a, int b ) { return a > b ? b : a; } int sum( int a, int b ) { return a + b; }

运行结果: 在这里插入图片描述 5.指针数组 指针数组是指数组中的元素都是指针变量,即数组的元素都是地址。常用于字符串数组的操作。 指针数组的定义如下:

类型说明符 *指针变量名[长度];

例5:给定5个字符串,然后统计字符串的最大长度。 参考代码:

#include"stdio.h" #include"string.h" #define N 5 int main() { int i, length, len; char *str[N] = { "C/C++", "computer", "programming", "pragma", "once" }; char *maxLenStr; length = 0; for( i=0; i length = len; maxLenStr = str[i]; } } printf( "最长字符串是:%s, 其长度为:%d\n", maxLenStr, length ); return 0; }

运行结果: 在这里插入图片描述 说明:在第7行代码,字符串数组中的每个元素均是字符串常量,将其赋值给左端的指针数组,在不同C语言编译器中对其处理的结果是相同的,但是会出现告警信息:将字符串常量赋值为字符指针变量。这是由指针数组中的元素没有进行初始化导致的。

—————————————————————— 未完待续!



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有