zoukankan      html  css  js  c++  java
  • 【改正总结】指针的局限性,scanf() 和 void*指针


    反思

    【一些感悟】内存和指针
      针对这篇文章中 “scanf() 和 数组” 小节存在的事实错误,及我认为的,C 中存在的一些不得已的缺陷。
      我做了总结,并通过 Blog 记录下来。

    本篇主要从两个点来阐述:
    1.【一些感悟】内存和指针 中 “void* 空类型指针” 小节提到的代码。
    2.scanf() 的参数。

     判断传入的指针类型

    简单的冒泡排序:

    void BubbleSort(void* array,int count)//注意第一个参数,我写的是 void*
    {
    	int i, j, temp, flag = 1;
    	for (j = 0; flag == 1; j++)
    	{	
    		flag = 0;
    		for (i = 0; i < count - j; i++)
    		{
    			if (array[i] < array[i + 1])
    			{
    				memswap(array[i + 1], array[i], sizeof array[i])
    				//由于我并不知道传入数组的类型,交换数据只能通过操作内存
    				//memcpy()用来交换内存,详细定义在下方
    				flag = 1;
    			}
    		}
    	}
    }
    

    memswap()的定义:

    void memswap(void* a,void* b,int size){
    	void* temp = malloc(size);
    	memcpy(temp,a,size);memcpy(a,b,size);memcpy(b,temp,size);
    	free(temp);
    }
    

    可以看出来,这段代码是错误的,因为我在排序函数中试图引用 void* 。

      我的目的是拓宽一个函数的适用范围,使得其不仅仅只针对一种数据类型排序,然而 C 对这样的传参方式无能为力,单从一个 void* 没办法判断实参的数据类型。

      老师为我提供了下图这样的解决方法:
    在这里插入图片描述
      然而,很显然,这种解决方案的移植性很差(不同环境下,某些数据类型所占字节数不同)

      后来接触了标准库中的 qsort() 函数,琢磨了其思想后惊为天人——它使用了一个回调函数,通过让程序员完成比较工作来绕开 “无法判断实参数据类型” 的问题。
    (详细解决方法移步.【一些感悟】内存和指针 中 “void* 空类型指针” 小节。)

      至此,问题算是解决了,但解决得并不完美。

      对于排序来说,使用一个回调函数并不能算是一个方便的做法,显然这个事情变得比以前更复杂了。那么,为什么 qsort() 函数不直接判断实参的数据类型而是使用更为复杂的回调函数呢?
      因为C 对这件事无能为力。
      也可能是认为没有必要,也可能是没考虑到,更可能的原因是,这是 C 底层性的一个表现。
      我再举一个例子,用来佐证 C 对判断实参数据类型确实无能为力的事实。

     从 scanf() 的参数的角度解释

      这里也是对 【一些感悟】内存和指针 中 “scanf() 和 数组” 小节的事实错误的改正。

      我们认为,scanf() 函数本身在设计上存在不周到的地方。
      无论你传入的指针是什么类型的,它只会傻傻地按照指定的格式化格式,从传入的指针位置开始写入数据,无论是否已经超出了变量的引用范围。
      尽管在号称更安全的 scanf_s() 中,也只是要求程序员多传入一个参数,来表示写入的最大长度,有没有感觉很傻?
      标准库都如此做了,那么我们就更加无法实现了。

      所以,C 对判断实参数据类型的的确确是无能为力的。

  • 相关阅读:
    awk语法
    Linux 统计某个字符串出现的次数
    Linux 输出文件列数,拼接文件
    Linux之date
    C变量类型和作用域
    Java垃圾回收机制
    python 字符编码问题
    Linux文件和windows文件在 换行符的区别
    不要在 foreach 循环里进行元素的 remove/add 操作。remove 元素请使用 Iterator 方式,如果并发操作,需要对 Iterator 对象加锁
    Iterator和ListIterator
  • 原文地址:https://www.cnblogs.com/gaolihai/p/13149770.html
Copyright © 2011-2022 走看看