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

时间:2022-09-09 14:45:38

刚学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