C指针 的一些练习

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

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

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

做法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("
");
}

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("
");
}

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
");
		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
");
			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("
");
}

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
");
		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
");
		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
");
			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("
");
}

注意:按照我的写法,开始赋值的时候,需要置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
");
		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
");
		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);
}
原文地址:https://www.cnblogs.com/qq952693358/p/5479636.html