数据结构结课作业日记

直到昨天中午,我还在因为读错题而疯狂学习新知识。

把整个任务脑补成了一个巨大的任务的错误太可怕了,以后要记住这次的教训,简直是白费了一天多的功夫。

不过这两天也不仅仅做这个任务,还复习了计算机网络,但是考试居然不是今天,是下周的今天。

这种事情怎么老是搞错呢。。。

算了都是好事不在意它。

结课作业中的问题

长久不用C语言,导致语言基础爆炸,很多东西忘记怎么使用,频频报错。

写两篇日志,分别是C语言的语法方面的问题和C语言算法的问题,本篇是语法问题。

指针和数组

这个问题一直是问题,在学C语言的时候草草就过去了,没有细致探讨,这里进行一定的实用性探讨。

  1. 数组名是数组首元素地址
    数组名和指针一样,存储的是地址,特殊在数组名内存储的是数组本身首元素的地址。
    一个词叫做解引用,把一个地址对应的数据取出就是解引用。
    对于一个数组a[N],我们进行了三步:第一步,取出数组元素首地址;第二步,目标地址=首地址+sizeof(type)*N,得到目标a[N]的地址;第三步,对地址解引用。
    对于一个指针p,只有两步,对p的地址解引用,获取到p的值,也就是p指向目标的地址;再对这个目标地址再次解引用,获得目标元素。

数组名!=数组指针,而是等于数组首元素指针。


  1. 一维数组可以和一维指针混用,二维数组可以喝二维指针混用吗?不可!

首先我们强调,把多维数组当做一维数组看待。
比如char arr[3][3],我们就要把它当做一维数组,内里元素分别为arr[0]arr[1]arr[2],这三个char [3]型的数组。

为什么?
我们先来看二维数组名代表了什么在代码中:

代码1:
char buf[2][2]={{1,2},{3,4}};
char *p = buf;
编译结果:

warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]

代码2:
char buf[2][2]={{1,2},{3,4}};
char (*p)[2] = buf;
编译结果:
无警告信息

显然,二位数组的数组名指针类型是char*[2]型,我们应当把二维乃至多维数组看成嵌套型的一维数组,也就是俄罗斯套娃数组,我们可以看到,数组名指针指向的首元素指针既可以是普通变量,也可以是一维或多维数组。

  1. 那么如何用指针来指向数组呢?
    数组中的元素排列是顺序排列的,也就是一横排一横排连续,所以有以下代码可以用指针指向数组并且调用。
#include<stdio.h>
#include<stdlib.h>

#define ROW 2
#define COLUMN 2
int main(void)
{
    char buf[ROW][COLUMN]={{1,2},{3,4}};
char *p = (char*)buf;
//访问buf[x][y],即访问p[x*COLUMN+y]
printf("buf = %d,%d,%d,%d\r\n",p[COLUMN*0+0],p[COLUMN*0+1],p[COLUMN*1+0],p[COLUMN*1+1]);
system("pause");
return 0;
}

结果是这样



通过这个试验,我们可以了解到如何用指针来管理数组了。

指针传递、引用传递

函数中有各种参数,普通的直接调用没有什么可说的,仅仅是新建一个值,只存活在函数调用期间,而函数麻烦而又有用的地方就在这指针传递和引用传递。

  1. 二者有什么共同点?
    都是在函数中操作实参地址的,而值传递操作的不是实参地址。

  2. 有什么不同点?
    引用的规则是被引用的同时必须被初始化,同时不能有NULL引用,引用必须与合法的存储单元关联。
    一旦引用倍初始化,就不能改变引用的关系。
    而指针可以任何时候被初始化,可以是NULL,可以随时改变所指的对象。

  3. 二者不同的根本原因。
    从概念上讲。指针从本质上讲就是存放变量地址的一个变量,在逻辑上是独立的,它可以被改变,包括其所指向的地址的改变和其指向的地址中所存放的数据的改变。

    而引用是一个别名,它在逻辑上不是独立的,它的存在具有依附性,所以引用必须在一开始就被初始化,而且其引用的对象在其整个生命周期中是不能被改变的(自始至终只能依附于同一个变量)。

用一段这个函数,展示下使用流程。

#include<stdio.h>
#include<stdlib.h>

#define ROW 2
#define COLUMN 2

typedef struct TEST
{
    int a;
    int b[5];
    int *c;
}testOf;

void tt(testOf *t);
void ttt(testOf &t);
int main(void)
{
    testOf testa,testb;
    testOf *te;
    testOf *teb=&testb;
    te=&testa;
    testa.a=8;
    for(int i=0;i<5;i++){
    tt(te);
    ttt(testa);
    ttt(testb);
    tt(teb);
    }
    teb=te;
    
    printf("%d%d\n",testa.a,testa.c);
    system("pause");

    return 0;
}
void tt(testOf *t)
{
    
    t->a++;
    printf("%d\n",t->a);

    t->c=&t->a;
}
void ttt(testOf &t)
{
    t.a=100;
    printf("%d\n",t.a);

}

函数多返回值

很多时候,我们都会碰到一个函数需要多个返回值,但是一个函数的返回值只有一个,如何用一个函数返回多个值呢?

想到指针就对了,我们可以在参数中使用指针参数,传递我们主函数中的参数,通过这个函数来影响实参。

我很喜欢一句话就是“编程的本质不就是改变量吗?”先有量的输入,然后改变成很多量,变型、变数、计算都是改变量。

输入流

输出的方法千篇一律,大多时候就是好看点和不好看的区别。

每次写c的时候,做题没感觉,但是只要是写整个程序就会出现各种难受的问题,最大的问题就是输入的问题。

如何能够方便输入、快速输入经常会成为一个大问题。

如何能够快速输入呢?
我们就想到一个方法,用空格隔开数组中的每一个数,用回车来确定。
这样不仅能清晰看到我们的输入,也比一直敲数字敲回车优雅。

粗略代码如下

#include <stdio.h>
int main(){
    int num;
    int i=0;
    int arr[10];
   while(1){
        scanf("%d",&num);
        char c=getchar();
        arr[i++]=num;
        if(c=='\n'){
            break;
        }
   }
  return 0;
}

getchar();读走了空格和回车并且在下面判定,空格再次循环,回车退出。

因为这次是为了给结课作业中的二维数组邻接表做输入,我就简单再写一个给二维数组邻接表赋值的详细代码。

#include<stdio.h>
#include<stdlib.h>

#define MAX_V_NUM 10
#define MAX_INT 999 //不可能数
//#define MAX_CITY_NUM 10

typedef struct TEST
{
    char chengshi[20] ;
    int arcsM[MAX_V_NUM][MAX_V_NUM];
    int Vnum,Lnum;
    int *c;
}testOf;

/*
typedef struct CITY
{
    testOf city[MAX_CITY_NUM];
}TheWord
*/

void init(testOf *map);//初始化邻接表,每个点到其他店为不可能值,到自己为0;
void mapIn(testOf &map);//手动输入邻接表,按行输入,空格分开数,回车分开行。
void mapShow(testOf *map);//展示邻接表



int main(void)
{
    testOf map,arcs;
    testOf *pmap;
    testOf *parcs;
    pmap=&map;
    parcs=&arcs;

    init(pmap);
    mapShow(pmap);
    mapIn(map);
    mapShow(pmap);

    system("pause");
    return 0;
}

/*初始化邻接表,*/
void init(testOf *map)
{
    int i,j;
    map->Vnum=MAX_V_NUM;
    for(i=0;i<MAX_V_NUM;i++)    //邻接矩阵的初始化
    {
        for(j=0;j<MAX_V_NUM;j++)
        {
            if(i==j)
            {
                map->arcsM[i][j]=0;
            }
            else
            {
                map->arcsM[i][j]=MAX_INT;
            }
        }
    }
}

/*手动输入邻接表*/
void mapIn(testOf &map)
{
    int num;
    int i=0;
    int j=0;
    int Vtime;
    printf("请输入城市中重要站点的数目\n");
    scanf("%d",&map.Vnum);
    Vtime=map.Vnum;
    getchar();

    printf("请输入邻接表值,格式为1 2 3 4,将这4个数赋值给邻接矩阵第一排\n");

/*为邻接表手动赋值,0代表不改变*/
    for(i=0;i<map.Vnum;i++) 
    {   
        printf("现在是第%d行,共有%d行\n",i+1,map.Vnum);
        for(j=0;j<map.Vnum;j++)
        {
            scanf("%d",&num);
            char c=getchar();

            if(num!=0 && map.arcsM[i][j]!=0)
            {
                map.arcsM[i][j]=num;
            }
            /*
            if(c==' '){
                Vtime--;
                if(Vtime==1){
                    break;
                }
            }
            */
            if(c=='\n'){
                break;
            }
        }
    }
}

/*展示邻接表*/
void mapShow(testOf *map)
{
    printf("--------此表如下----------\n");
    int i,j;
        for(i=0;i<map->Vnum;i++)    
    {   

        for(j=0;j<map->Vnum;j++)
        {
            printf("%d ",map->arcsM[i][j]);
        }
        printf("\n");
    }
}

这段代码实现了通过空格隔开数据,分行输入数据到数组中,效果如下

虽然没有鲁棒性,没有错误显示,不过有了一个大的架子,试验中使用还是足够的。

本次实验期间任务繁多,如果在最后较为空闲,会补出等同这段代码,会更加美观更加健壮。


以下是我遇到问题后,上网查资料帮助到我的文章。

————————————————
版权声明:本文为CSDN博主「千淘万漉」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/matrix_google/article/details/76595439
————————————————
版权声明:本文为CSDN博主「魏波-」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weibo1230123/article/details/75541862

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343