逛奔的蜗牛

我不聪明,但我会很努力

   ::  :: 新随笔 ::  ::  :: 管理 ::
数组和指针这东西有时还是比较麻烦:
指针是很危险的,但同时也是非常强大的,就如一个高手拿AWP和一个菜鸟拿AWP一样,一个是最恐怖的魔鬼,另一个却是被虐的对象。
const int *p 和 int const *p 指的是数组的内容不能改变。
int * const p 指的是指针名不能改变。谁在 const 后面,谁就是不变的。
 
二维数组动态分配:
int **p;
int row = 5;
int column = 10;
p = new int*[row];
for (int i=0; i<row; i++) {
        p[i] = new int[column];
}
 
指针即是地址(0xf0765fea),是无符号整数,占用四个字节,32位。怎么判断一个指针所指向的类型?
去掉一个 * 和变量名后所留下的部分就是指针所指向的类型。
如 int *p; 去掉一个 * 和变量名 p 后就只有 int 了,所以 p 指向 int 的整形数。
float **p; 则 p 指向的类型是 float *,即 float 类型的指针,或 float 类型的地址,也即数组。
那么在给 p 分配内存时,p = new float*[23],即指向一些
在C或C++中有一个很好的地方是,即使你定义的变量是指针,但可与用访问数组下标的方法来访问指针所指向的数据;int **p;   *(*(p+i) + j) 等同于 p[i][j],使用数组下标来访问更直观。
 
使用变量来声明数组的长度,使程序更具有健壮性. int length = 10; int array[length].
给定一个二维数组和一个位置数loc,怎么确定这个数对应数组中的那一个位置?
array[loc / column][loc % column]
 
当定义一个数组时,但没有初始化,这时数组的内容是还是原来内存中的值。
 
void * 的使用
可以把任何类型的指针直接传给 void* 的变量。
但是反过来,却不能直接把 void* 传给其他类型指针,必须明确的进行强制类型转换
int *pi;
void * pv = pi; // Ok
float *pf = (float*)pv; // Ok
double *pd = pv; // Error
 
char *str = (char*)malloc(sizeof(char) * number);
malloc分配一段内存,返回这段内存的首地址,其值为 void *,这样,不管什么类型的指针都可以用这个函数来进行内存分配,void * 实现了相当于 C++ 中的函数模板的功能,实现了在C中的多态。各种类型说明符,就是为了说明每次进行存取的时候操作多少字节。
 
数组名是这个数组的首地址,与他的第一个元素的地址是指向同一个地址,但数组却是一个常量,只能进行右值计算,是不可改变的。指针变量也是指向地址,但指针变量是可以改变的,可以进行右值计算,也可以左值计算。
 
字符数组的结束符号是'\0',其整型值是 0,即 NULL
虽然这样,但在OpenGL中,如在 glGenTextures 的调用中,经常用的是第一个元素的地址,而不是用数组名。
 
用数组实现折半查找:
在最坏的情况下,1024个元素只需要进行10查找,但查找前要先排序
返回要查找的数在数组的下标,当不在数组中是,返回 -1,因为数组下标是从0开始的。
int binarySearch(const int *p, const int g, int low, int height) {
         int mid;
 
         while (low <= height) {
                 mid = (low + height) / 2;
                 if (g < p[mid]) {
                          height = mid - 1;
                 } else if (g > p[mid]) {
                          low = mid + 1;
                 } else {
                          return mid;
                 }
          }
 
          return -1;
}
 
快速排序:
void quickSort(int *p, int low, int height) {
          if (low >= height) {
                  return;
          }
 
          const int l = low;
          const int h = height;
          int ref = p[(low + height)/2];
          int temp = 0;
 
          // 如果没有等于这个条件,那么如 3, 2, 1时,就会造成下一次排序为1,2 ; 2, 3,多出来一个 2
          while (low <= height) {
                    // 找到大于等于 ref 的数,这里很重要,如果用 <= 的话,即找到比 ref 大的数,
                  // 可能会造成数组越界
                    while (p[low] < ref) { 
                              low++;
                    }  
                    while (p[height] > ref) {
                              height--;
                    }
  
                    // 这个条件是必须的,否则不能正确排序, l1,3,4,2,2,3,h5, 3为ref
                    // 第一次排序后,1, 3, l4, 2, h2, 3, 5
                    // 第二次排序后,1, 3, 2, lh2, 4, 3, 5,这时还可以进行下一次排序
                    // 第三次排序,h仍在2处,但l要找大于等于他的数,即1, 3, 2, h2, l4, 3, 5
                    // 如果没有这个条件,那么就要进行交换,1, 3, h2, 4, 2, l3, 5,有错误发生
                    if (low <= height) {
                              temp = p[low];
                              p[low] = p[height];
                              p[height] = temp;
                              low++;
                              height--;
                    }
  
          }
 
          quickSort(p, low, h);
          quickSort(p, l, height);
          // 第一次压入(low, height)
     // 从栈中取出一对(low, height)进行每个片段的排序
          // 每排完一遍后,即上面的while执行完一次,压入(low,h)和(l,height)
     // 利用栈消除递归
 
          return;
}
 
排序一般当元素个数大于三十个时利用快速排序的速度比较快,当元素个数小于三十个时,利用选择排序比较好,所以一般都是选择排序和快速排序结合起来使用。
posted on 2010-12-17 17:30 逛奔的蜗牛 阅读(534) 评论(0)  编辑 收藏 引用 所属分类: C/C++

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理