欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C指针 的一些练习

程序员文章站 2024-03-07 20:37:09
...

注:此篇是我使用指针敲的一些题目的集成,有一些代码是重复的(挠头)。这样做的目的是进行前后的一些比较和收获一些心得(?)。

关于上一次我上台的题目:

题目:输入十个整数,进行排序。

做法1:(传递指针p)

#include <cstdio>
#include <iostream>
#include <string.h>
using namespace std;

void swap(int *p)
{
    int i,j;
    int t;
    for(i = 1 ; i <= 10; i++)
    {
        for(j = i + 1; j <= 10; j++)
        {
            if(*(p + j) < *(p + i))
            {
                t = *(p + i);
                *(p + i) = *(p + j);
                *(p + j) = t;
            }
        }
    }
    
    for(i = 1; i <= 10; i++)
    {
        printf("%d ",*(p + i));
    }
    printf("\n");
}

int main()
{
    int a[10];
    memset(a,0,sizeof(a));
    
    int i,j;
    int *p;
    p = a;
    
    for(i = 1; i <= 10; i++)
    {
        scanf("%d",&a[i]);
    }
    
    swap(p);
    
    return 0;
}

做法2:(传递数组名)

#include <cstdio>
#include <iostream>
#include <string.h>
using namespace std;

void swap(int a[])
{
    int i,j;
    int t;
    for(i = 1 ; i <= 10; i++)
    {
        for(j = i + 1; j <= 10; j++)
        {
            if(a[j] < a[i])
            {
                t = a[i];
                a[i] = a[j];
                a[j] = t;
            }
        }
    }
    
    for(i = 1; i <= 10; i++)
    {
        printf("%d ",a[i]);
    }
    printf("\n");
}

int main()
{
    int a[10];
    memset(a,0,sizeof(a));
    
    int i,j;
    
    for(i = 1; i <= 10; i++)
    {
        scanf("%d",&a[i]);
    }
    
    swap(a);
    
    return 0;
}

链表

有段时间没敲链表了(挠头),重新实现下,发现还是很多地方出错了:(
经过漫长时间的debug,发现一个原因是,在主函数里面定义的整形变量,在函数pdelete里面缺少了对其的定义,编译居然过了(挠头)
写了两遍。贴个最后一次实现的代码吧。

链表的创建,输出,插入和删除

#include <cstdio>
#include <iostream>
#include <stdlib.h>
using namespace std;

struct Node
{
    int data;
    Node *next;
};

void IniNode(Node *head)
{
    head = (Node *)malloc(sizeof(Node));
    if(head == NULL)
    {
        printf("Overflow\n");
        exit(1);
    }
    
    head -> next = NULL;
    head -> data = -1;
}

Node *Creat()
{
    Node *head;
    IniNode(head);
    
    Node *p1,*p2;
    
    p1 = p2 = head;
    
    while(p1 -> next != NULL || p1 == head)
    {
        int a = 0;
        scanf("%d",&a);
        
        if(a < 0)
        {
            p1 -> next = NULL;
            break;
        }
        
        p1 = (Node *)malloc(sizeof(Node));
        if(p1 == NULL)
        {
            printf("Overflow\n");
            exit(1);
        }
        
        p1 -> data = a;
        p2 -> next = p1;
        p2 = p1;
    }
    
    return head;
}

void output(Node *head)
{
    Node *p = head -> next;
    
    while(p != NULL)
    {
        printf("%d ",p -> data);
        
        p = p -> next;
    }
    
    printf("\n");
}

void pinsert(Node *head)
{
    Node *p1,*p2;
    
    p1 = p2 = head;
    
    int i_data = 0,num = 0;
    
    scanf("%d%d",&num,&i_data);
    
    int i,j;
    
    for(i = 1; i <= num; i++)
    {
        p2 = p1;
        p1 = p1 -> next;
    }
    
    Node *p;
    p = (Node *)malloc(sizeof(Node));
    if(p == NULL)
    {
        printf("Overflow\n");
        exit(1);
    }
    
    p -> next = p1;
    p -> data = i_data;
    p2 -> next = p; 
    
    output(head);
}

void pdelete(Node *head)
{
    Node *p1,*p2;
    
    p1 = p2 = head;
    
    int d_num = 0;
    scanf("%d",&d_num);
    
    int i,j;
    for(i = 1; i <= d_num; i++)
    {
        p2 = p1;
        p1 = p1 -> next;
    }
    
    p1 = p1 -> next;
        free(p2 -> next); // 勿忘我
    p2 -> next = p1;
    
    output(head);
}

int main()
{
    Node *head;
    
    head = Creat();
    
    output(head);
    
    pinsert(head);
    
    pdelete(head);
    
    return 0;
}

链表错误小结

  • 构建部分:
void IniNode(Node *head)
{
    head = (Node *)malloc(sizeof(Node));
    if(head == NULL)
    {
        printf("Overflow\n");
        exit(1);
    }
    
    head -> next = NULL;
    head -> data = -1;
}

Node *Creat()
{
    Node *head;
    IniNode(head);
    
    Node *p1,*p2;
    
    p1 = p2 = head;
    
    while(p1 -> next != NULL || p1 == head)
    {
        int a = 0;
        scanf("%d",&a);
        
        if(a < 0)
        {
            p1 -> next = NULL;
            break;
        }
        
        p1 = (Node *)malloc(sizeof(Node));
        if(p1 == NULL)
        {
            printf("Overflow\n");
            exit(1);
        }
        
        p1 -> data = a;
        p2 -> next = p1;
        p2 = p1;
    }
    
    return head;
}

1. 在Creat里面,初始化Node的时候不能置NULL:

    Node *head = NULL; // Error.
    IniNode(head);

2. 其次,在构建链表的时候,需要注意p2 始终跟在 p1的后面,起到link的作用。

    p1 = (Node *)malloc(sizeof(Node));
    ···
    p1 -> data = a;
    p2 -> next = p1; // 这句话不要忘记
    p2 = p1;

3. while循环条件,我的写法是刚刚开始时将p1 和p2 ,指向头节点。所以循环条件得:

while(p1 -> next != NULL || p1 == head)

否则,开始时p1 -> next == NULL就没有办法进入循环进行输入。

  • 输出部分:
void output(Node *head)
{
    Node *p = head -> next;
    
    while(p != NULL)
    {
        printf("%d ",p -> data);
        
        p = p -> next;
    }
    
    printf("\n");
}

注意:按照我的写法,开始赋值的时候,需要置p为 head -> next,否则无法进入循环。

  • 插入部分:
void pinsert(Node *head)
{
    Node *p1,*p2;
    
    p1 = p2 = head;
    
    int i_data = 0,num = 0;
    
    scanf("%d%d",&num,&i_data);
    
    int i,j;
    
    for(i = 1; i <= num; i++)
    {
        p2 = p1;
        p1 = p1 -> next;
    }
    
    Node *p;
    p = (Node *)malloc(sizeof(Node));
    if(p == NULL)
    {
        printf("Overflow\n");
        exit(1);
    }
    
    p -> next = p1;
    p -> data = i_data;
    p2 -> next = p; 
    
    output(head);
}

1. for循环条件需要根据p1 和 p2的初始指向确定。

    p1 = p2 = head;
    ···
    for(i = 1; i <= num; i++) // <= 
    {
        p2 = p1;
        p1 = p1 -> next;
    }

否则会导致崩溃,指向错误。

2. 创立的新结点 同样需要 malloc语句

    Node *p;
    p = (Node *)malloc(sizeof(Node));
    if(p == NULL)
    {
        printf("Overflow\n");
        exit(1);
    }
  • 删除部分:
    (这里指的是删除结点)
void pdelete(Node *head)
{
    Node *p1,*p2;
    
    p1 = p2 = head;
    
    int d_num = 0;
    scanf("%d",&d_num);
    
    int i,j;
    for(i = 1; i <= d_num; i++)
    {
        p2 = p1;
        p1 = p1 -> next;
    }
    
    p1 = p1 -> next;
        free(p2 -> next); // 勿忘我
    p2 -> next = p1;
    
    output(head);
}

注:和insert一样,需要根据p1 和p2 的初始指向确定循环范围。

  • 最后需要释放内存
void pfree(Node *head)
{
    Node *p1,*p2;
    p1 = p2 = head;
    
    while(p1 -> next != NULL)
    {
        p2 = p1;
        p1 = p1 -> next;
        free(p2);
    }
    
    if(p1 == head)
    free(p1);
}