TC程式碼在VC++6.0及VS2017中的正常執行
最近在複習資料結構,用的書是清華學嚴蔚敏老師的經典教材,書上的程式碼需要自己全敲一遍方便記憶,然後想偷懶,就從網上找了好幾個別人的程式碼,想對照著來打,結果程式碼在VS2017中老是報錯,一直無法編譯通過,覺得可能是編譯器的問題,畢竟人家的程式碼是寫給Turbo C2.0的,就換成VC++6.0,一跑還是報各種錯誤,最終只好用TC2.0跑,結果是程式碼是正常的,TC上跑的很歡暢,但是,中文是不支援的,所以,那就是輸出一堆亂碼。
本著發現問題,解決問題的正確人生態度,在犧牲掉一些本來就不多的腦細胞後,終於把問題解決掉,讓C程式碼無壓力的在VC60和VS上跑的無比歡暢,具體請看下面的操作:
0x01 先看C的程式碼
#include <stdio.h> #include <malloc.h> #include <stdlib.h> #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 #define OVERFLOW -2 #define list_init_size 100 //線性表儲存空間的初始分配量 #define LISTINCREMENT 10 //線性表儲存空間的分配增量 typedef int Status; typedef int ElemType; typedef struct{ ElemType *elem; //儲存空間基址 int length; //當前長度 int listsize; //當前分配的儲存容量(以sizeof(ElemType)為單位) }SqList; Status InitList_Sq(SqList &L){ //構造一個空的線性表L L.elem =(ElemType * )malloc(list_init_size*sizeof(ElemType)); if(!L.elem )exit(OVERFLOW);//儲存分配失敗 L.length =0; //空表長度為0 L.listsize =list_init_size;//初始儲存容量 return OK; }//Initlist_Sq Status ListInsert_Sq(SqList &L,int i,ElemType e){ //在順序線性表L中第i個位置之前插入新的元素e, //i的合法值為1<=i<=ListLength_Sq(L)+1 ElemType *p,*q,*newbase; //定義指標 if(i<1||i>L.length +1) return ERROR; //i值不合法 if(L.length >=L.listsize ){ //當前儲存空間已滿,增加分配 newbase=(ElemType * )realloc(L.elem ,(L.listsize +LISTINCREMENT)*sizeof(ElemType)); if(!newbase)exit(OVERFLOW); //儲存分配失敗 L.elem =newbase; //新基址 L.listsize +=LISTINCREMENT; //增加儲存容量 } q=&(L.elem [i-1]); //q為插入位置 for(p=&(L.elem [L.length -1]);p>=q;--p) *(p+1)=*p; //插入位置及之後的元素右移 *q=e; //插入e ++L.length ; //表長增1 return OK; }//ListInsert_Sq Status ListDelete_Sq(SqList &L,int i,ElemType &e){ //在順序線性表L中刪除第i個元素,並用e返回其值 //i的合法值為1<=i<=ListLength_Sq(L) ElemType *p,*q; //定義指標 if((i<1) || (i>L.length )) return ERROR; //i值不合法 p=&(L.elem [i-1]); //p為被刪除元素的位置 e=*p; //被刪除元素的值賦給e q=L.elem +L.length -1; //表尾元素的位置 for(++p;p<=q;++p) *(p-1)=*p; //被刪除元素之後的元素左移 --L.length ; //表長減1 return OK; }//ListDelete_sq void display(SqList L) { //定義for迴圈函式 int i; for(i=0;i<=L.length -1;i++) printf("%d\n",L.elem [i]); } int LocateElem_Sq(SqList L,ElemType e) { //在順序線性表L中查詢第1個值與e滿足compare()的元素的位序 //若找到,則返回其在L中的位序,否則返回0 ElemType *p; int i=1; //i的初值為第一個元素的位序 p=L.elem ; //p的初值為第一個元素的儲存位置 while(i<=L.length && *p++!=e) ++i; if(i<=L.length) return i; else return 0; }//LocateElem_Sq void MergeList_Sq(SqList La,SqList Lb,SqList &Lc ){ //已知順序線性表La和Lb的元素按值非遞減排列 //歸併La和Lb得到新的順序線性表Lc,Lc的元素也按非遞減排列 ElemType *pa,*pb,*pc,*pa_last,*pb_last; pa=La.elem ; pb=Lb.elem ; Lc.listsize =Lc.length =La.length +Lb.length ; pc=Lc.elem =(ElemType *)malloc(Lc.listsize *sizeof(ElemType)); if(!Lc.elem )exit(OVERFLOW); //儲存分配失敗 pa_last=La.elem +La.length -1; pb_last=Lb.elem +Lb.length -1; while(pa<=pa_last && pb<=pb_last) { //歸併 if(*pa<=*pb) *pc++=*pa++; else *pc++=*pb++; } while(pa<=pa_last) *pc++=*pa++; //插入La的剩餘元素 while(pb<=pb_last) *pc++=*pb++; //插入Lb的剩餘元素 }//MergeList_Sq void main() { /* SqList L;//定義線性表 InitList_Sq(L);//呼叫空表 //插入資料 ListInsert_Sq(L,1,10); ListInsert_Sq(L,2,20); ListInsert_Sq(L,1,30); ListInsert_Sq(L,3,40); printf("插入後:\n"); display(L);//呼叫迴圈函式 ListInsert_Sq(L,3,100);//在L表第三個位置插入100 printf("插入後:\n"); display(L); ElemType e;//定義e ListDelete_Sq(L,3,e);//刪除L表的第三個元素,用e表示 printf("刪除後:\n"); display(L); printf("被刪除元素:%d\n\n\n\n",e); */ SqList La,Lb,Lc; InitList_Sq(La); ListInsert_Sq(La,1,3); ListInsert_Sq(La,2,5); ListInsert_Sq(La,3,8); ListInsert_Sq(La,4,11); printf("La插入後:\n"); display(La); InitList_Sq(Lb); ListInsert_Sq(Lb,1,2); ListInsert_Sq(Lb,2,6); ListInsert_Sq(Lb,3,8); ListInsert_Sq(Lb,4,9); ListInsert_Sq(Lb,5,11); ListInsert_Sq(Lb,6,15); ListInsert_Sq(Lb,7,20); printf("Lb插入後:\n"); display(Lb); MergeList_Sq(La,Lb,Lc); printf("歸併後:\n"); display(Lc); printf("\n"); int a=LocateElem_Sq( Lc, 5); printf("%d\n",a); }
這是關於線性表的的練習,在TC中跑的很好,有同學說TC在win764下沒法安裝,一會我給你個不安裝可以直接執行的。
0x02 VC++6.0
建立一個標準的win32控制檯程式:
程式碼直接複製到VC6中,會報下圖的錯誤:
不期的檔案末尾,直觀感覺應該是包含檔案有問題,那就在#include那裡開始註釋大法,果然,註釋掉不報這個錯誤了,變成各種未定義,那就是說註釋掉了沒用的,但也沒有引進有用的標頭檔案,果然引入stdafx.h和iostream這兩個基礎頭,好了,萬事大吉,看下圖。
0x03 VS2017
建立一個VS中的C++Hello程式:
程式碼直接複製到VS中,會報下圖的錯誤(開始時還報本地函式非法):
根據VC中的經驗修改包含的標頭檔案為:
#include "pch.h"
#include <iostream>
然後就順利生成,點執行,如下圖:
0x04 總結
從C到C++來了兩個加號,從C++到C#又多了兩個加號,但本質上他們還是C家的人,所以傳承上是沒問題的,只是在標頭檔案結構發生了很大變化,只要因時而動,都能順利解決掉!