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

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

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

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

C指针 的一些练习的更多相关文章

  1. TODO:Golang指针使用注意事项

    TODO:Golang指针使用注意事项 先来看简单的例子1: 输出: 1 1 例子2: 输出: 1 3 例子1是使用值传递,Add方法不会做任何改变:例子2是使用指针传递,会改变地址,从而改变地址. ...

  2. enote笔记法使用范例(2)——指针(1)智能指针

    要知道什么是智能指针,首先了解什么称为 “资源分配即初始化” what RAII:RAII—Resource Acquisition Is Initialization,即“资源分配即初始化” 在&l ...

  3. C++虚函数和函数指针一起使用

    C++虚函数和函数指针一起使用,写起来有点麻烦. 下面贴出一份示例代码,可作参考.(需要支持C++11编译) #include <stdio.h> #include <list> ...

  4. C++11 shared_ptr 智能指针 的使用,避免内存泄露

    多线程程序经常会遇到在某个线程A创建了一个对象,这个对象需要在线程B使用, 在没有shared_ptr时,因为线程A,B结束时间不确定,即在A或B线程先释放这个对象都有可能造成另一个线程崩溃, 所以为 ...

  5. c 数组与指针的使用注意事项

    数组变量和指针变量有一点小小的区别 所以把数组指针赋值给指针变量的时候千万要小心 加入把数组赋值给指针变量,指针变量只会包含数组的地址信息 而对数组的长度一无所知 相当于指针丢失了一部分信息,我们把这 ...

  6. Marshal.Copy将指针拷贝给数组

    lpStatuss是一个UNITSTATUS*的指针类型实例,并包含SensorDust字段 //定义一个数组类型 byte[] SensorDust = new byte[30] //将指针类型拷贝 ...

  7. C++智能指针

    引用计数技术及智能指针的简单实现 基础对象类 class Point { public: Point(int xVal = 0, int yVal = 0) : x(xVal), y(yVal) { ...

  8. EC笔记:第三部分:17、使用独立的语句将newed对象放入智能指针

    一般的智能指针都是通过一个普通指针来初始化,所以很容易写出以下的代码: #include <iostream> using namespace std; int func1(){ //返回 ...

  9. 智能指针shared_ptr的用法

    为了解决C++内存泄漏的问题,C++11引入了智能指针(Smart Pointer). 智能指针的原理是,接受一个申请好的内存地址,构造一个保存在栈上的智能指针对象,当程序退出栈的作用域范围后,由于栈 ...

  10. 智能指针unique_ptr的用法

    unique_ptr是独占型的智能指针,它不允许其他的智能指针共享其内部的指针,不允许通过赋值将一个unique_ptr赋值给另一个unique_ptr,如下面错误用法: std::unique_pt ...

随机推荐

  1. 如何实现在H5里调起高德地图APP?

    http://www.cnblogs.com/milkmap/p/5912350.html 这一篇文章,将讲述如何在H5里调起高德地图APP,并展示兴趣点.适合于展示某个餐馆,商场等,让用户自行选择前 ...

  2. (转)Elasticsearch索引mapping的写入、查看与修改

    mapping的写入与查看 首先创建一个索引: curl -XPOST "http://127.0.0.1:9200/productindex" {"acknowledg ...

  3. 深入理解python之二——python列表和元组

    从一开始学习python的时候,很多人就听到的是元组和列表差不多,区别就是元组不可以改变,列表可以改变. 从数据结构来说,这两者都应当属于数组,元组属于静态的数组,而列表属于动态数组.稍后再内存的分配 ...

  4. 常用软件安装及VS插件工具

    常用开发工具安装 开发环境 Visual Studio 2013 Microsoft SQL Server 2008 源代码管理 Git TortoiseGit GitScc Provider Cru ...

  5. ASP.NET Post方式提交

    public static string SendMsg(string fxPhone, string fxPassword, string toPhone, string msg) { try { ...

  6. centos迷你版,没有安装ifconfig命令

    ifconfig命令是设置或显示网络接口的程序,可以显示出我们机器的网卡信息,可是有些时候最小化安装CentOS等Linux发行版的时候会默认不安装ifconfig等命令,这时候你进入终端,运行ifc ...

  7. 摘自(http://www.ruanyifeng.com/blog/2011/07/linux_load_average_explained.html)

    理解Linux系统负荷   作者: 阮一峰 一.查看系统负荷 如果你的电脑很慢,你或许想查看一下,它的工作量是否太大了. 在Linux系统中,我们一般使用uptime命令查看(w命令和top命令也行) ...

  8. pandas练习(一)------ 了解数据

    探索Chipotle快餐数据 (相关数据见github) 步骤1 导入pandas库 import pandas as pd 步骤2 导入数据集 path1 = "./data/chipot ...

  9. Python: 用shell通配符匹配字符串,fnmatch/fnmatchcase

    问题:想使用Unix Shell 中常用的通配符(比如*.py , Dat[0-9]*.csv 等) 去匹配文本字符串 解决方案: 1. fnmatch 模块提供了两个函数—— fnmatch() 和 ...

  10. Java设计模式应用——组合模式

    组合模式实际上是一种树形数据结构.以windows目录系统举例,怎么样用java语言描述一个文件夹? 定义一个文件夹类,文件夹类中包含若干个子文件类和若干个文件类. 进一步抽象,把文件夹和文件都看做节 ...