C语言指针初始化的必要性以及指针变量与指针值的用法

刚学C语言指针时,只对其初始化一掠而过,导致在数据结构的编程中老是出现编译错误,既浪费时间又无益于于效率。为此,今天特地总结一下指针的初始化。

下面以开放定址法处理处理冲突的哈希表的测试文件作说明:

#include <stdio.h>
#include <stdlib.h>
#include "kfdz-hash.h"

int Hash(int key,int size){     //hash的构造函数
    return key%size;
}

void collision(int *hashValue, int hashSize){  //查看下一个地址
   
    *hashValue= (*hashValue+1)%hashSize;
} 

int main()
{
    int i,a = 0,b = 0;
    int *d ;
    int *e ;
    d = &a;       //若省去这一行会出现编译错误,因为此时的指针是“野指针”,不受“控制”
    e = &b;       //若省去这一行会出现编译错误,因为此时的指针是“野指针”,不受“控制”
    
    int n = -1000;
    
    int Hash(int,int);
    void collision();
    int hashsize = 4;
    int key[] = {11,1,2,3,4,5,6};
    Node  *np1 = (Node *)malloc(sizeof(Node));
    
    HashTable *H = (HashTable *)malloc(sizeof(HashTable));  //需为其开辟空间,否则下面的调用会出错,类似于“野指针”
    InitHash(H ,hashsize, Hash,collision);
    
    printf("插入后全部输出以及冲突次数\n");
    for(i = 0; i < 6; i ++){                                  //插入元素并判断是否重构
            if(H->count >= H->size)H = expandHash(H,2 * H->size);
            InsertHash( H , key[i] );}
            
    for(i = 0; i < 6; i ++){
             *e = 0;                                        //搜索元素并输出
             printf("%d ",SearchHash( H, key[i] , d, e)->key);
             printf("%d\n",*e);} 
    
    
    printf("\n\n删除个别元素后全部输出\n");
    deleteHash(H, 5);                                     //删除元素
    deleteHash(H, 1);
    
    for(i = 0; i < 6; i ++){
            
         np1 = SearchHash(H, key[i],d,e);
         printf("%d ",np1 == NULL?n:np1->key);
    }
    printf("\n");
    
    DestroyHash(H);
    return 0;
}

需理解调用函数中的指针变量值改变并不影响原指针变量值,只有指针变量所指向的变量值改变才会影响原指针所指向的变量值。这里需注意指针变量的值以及指针变量所指向的变量值。

下面以哈希表的实现文件来说明:

#include <stdio.h>
#include <stdlib.h>
#include "kfdz-hash.h"

//初始化
Status InitHash(HashTable *H, int size, int (*hash)(int, int),
                void (*collision)(int *,int)){
                
                   int i;
                   H->rcd = (Node *)malloc(size*sizeof(Node));
                   //H->tag = (int *)malloc(size*sizeof(int));
                   if(H->rcd == NULL)return ERROR;
                   
                   for(i = 0; i < size; i ++)H->rcd[i].tag = 0;
                   H->size = size;
                   H->hash = hash;
                   H->collision = collision;
                   H->count = 0;
                   return OK;
                }

Status DestroyHash(HashTable *H){
      
      free(H); return OK;
      //else return ERROR;
}

Node *SearchHash(HashTable *H,int key,int *p , int *c){

       *p = H->hash(key, H->size);
       int a = 0;
       int *q = &a;
       *q = *p;
       while(1 == H->rcd[*p].tag && H->rcd[*p].key != key || -1 == H->rcd[*p].tag){
        
             H->collision(p,H->size);(*c) = *c + 1;
             if(*q == *p)break;//如果找一遍后回到原处就退出       
       }
       
       
       if(H->rcd[*p].key == key && 1 == H->rcd[*p].tag){ return  &H->rcd[*p];}
       else return NULL;
        
}

Status InsertHash(HashTable *H,int key){
     
     int a = 0,b = 0;
     int *c ;
     int *j ;
     c = &a;
     j = &b;
     
     if(NULL == SearchHash(H, key, j, c)){
        
        int k = *j;
        /*if( H->count >= H->size){
                printf("%d " , key);
                H = expandHash( H, 2 * (H->size));
                SearchHash(H,key,j,c);
                H->rcd[*j].key = key;
                H->rcd[*j].tag = 1;
                H->count++;
                return OK;
        }*/   
        /*省略代码为哈希表重构的执行,
        若此执行在search中进行,无法完成重构,
        因为重构得到的指针只是赋给search中的指针变量参数H,
        让其不指向传递过来的指针,无法改变原指针的指向,故重构失败。*/
        
        H->rcd[k].key = key;
        H->rcd[k].tag = 1;
        H->count++;
        return OK; 
     } 
    
    return ERROR;
}

Status deleteHash(HashTable *H,int key){

      int a = 0,b = 0; 
      int *c = &a;
      int *j = &b;
      
      if(SearchHash(H, key, j, c) != NULL){
        H->rcd[(*j)].tag = -1;
        return OK;
      }
      else return ERROR; 
}

HashTable * expandHash(HashTable *H,int expand){

      int i;
      HashTable *h = (HashTable *)malloc((H->size+expand)*sizeof(HashTable));
      if( h == NULL) return ERROR;
      
      InitHash(h , H->size+expand, H->hash,H->collision);
      for(i = 0; i < H->size; i++){
        if(H->rcd[i].tag == 1)InsertHash(h,H->rcd[i].key);
      }
      
      free(H);
      return h;
}

以下为哈希表的头文件:

#ifndef _KFDZ-HASH_H
#define _KFDZ-HASH_H

#define OK 1
#define ERROR 0

typedef int Status;
typedef struct node{
    int key;
    int tag;
}Node;

typedef struct {
   
   Node* rcd;
   int size;
   int count;
   int (*hash)(int key, int hashSize); //函数指针
   void (*collision)(int *hashValue,int hashSize);
}HashTable;



Status DestroyHash(HashTable *H);
Node *SearchHash(HashTable *H,int key,int *p , int *c);
Status InsertHash(HashTable *H,int key);
Status deleteHash(HashTable *H,int key);
HashTable *expandHash(HashTable *H,int expand);
Status InitHash(HashTable *H, int size, int (*hash)(int, int),
                void (*collision)(int *,int));

#endif



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值