20160203.CCPP体系详解(0013天)
生活随笔
收集整理的這篇文章主要介紹了
20160203.CCPP体系详解(0013天)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
程序片段(01):數組.c+02.數組初始化語法.c
內容概要:數組
///01.數組.c
#include <stdio.h>
#include <stdlib.h>//01.采用容器結構存儲數據的要點:
// 1.必須為每個數據分配獨立的存儲空間
// 2.必須為每個數據分配獨立的標識符(變量名稱)
//02.C語言之C99語法的特點:
// 針對于VC編譯器:
// 1.VC編譯器分配數組的時候必須靜態分配
// 靜態分配:在編譯時期確定數組所占據的內存尺寸(字節數)大小
// 2.數組長度必須為真常量(或常量表達式)
// 明確的數組元素個數
// 針對于GCC編譯器:
// 1.GCC編譯器分配數組的時候采用動態分配
// 動態分配:在執行時期確定數組所占據的內存尺寸
// 2.數組長度可以為偽常量(或變量)
// 不確定的數組元素個數(程序執行時期知道)
//03.偽常量的聲明方式:
// 在原始變量的前面添加一個偽常量標識前綴("const")
//04.關于常量的透徹分析:
// 偽常量:const int num = 1;
// 1.具備內存實體:
// 不允許直接進行修改,但允許間接進行修改
// 2.靜態分配:
// 在編譯時期確定偽常量的值
// 真常量:#define NUM 1
// 1.不具備內存實體:
// 既不允許直接修改,也不允許間接修改
// 2.預編譯決定:
// 在預編譯時期就已經決定了將宏名為了常量(整型,實型,字符型,字符串型)
int main01(void)
{const int num = 10;//常量表達式{但是該常量表達式的常量值可以經過間接改變,所以是偽常量}-->有內存實體#define NUM 1//真常量{一旦確定了真常量的值,就不允許修改真常量的數據}-->無內存實體//int a[num];//編譯的時候確定大小,靜態分配,VC不支持int a[NUM];//VC必須靜態分配,GCC可以動態分配system("pause");
}//05.關于數組使用的要點總結:
// 1.靜態數組分配方式:
// (1).int a[5] = {1, 2, 3, 4, 5};//數組元素的類型:int;數組整體的名稱:a;數組元素的個數:5;
// 數組元素的具體數據:1, 2, 3, 4, 5
// (2),靜態分配:在編譯時期就已經確定了數組所占用的內存地址以及內存尺寸(首地址+尺寸)
// 2.分配方式組成分析:
// (1).int:表明數組當中所存儲的每個元素的類型
// (2).a:表示數組整體的名稱(數組名)
// 數組名的本質是一個常量指針(偽常量)
// (3).{}:代碼塊兒分配方式,只能用于聲明數組的同時進行使用(既可以局部初始化也可以全部初始化)
// 3.sizeof:
// (1).是一個關鍵字,而不是一個函數
// (2).如果傳遞的是數組名,那么求取的內存尺寸是數組整體所占用的內存尺寸(區分數組整體和數組元素)
// 4.%p和%d的使用意義:
// (1).所以數據在內存當中的存儲實質都一樣,都是二進制數據
// (2).格式控制符只是決定了不同的解析方式:
// %d:內存數據按照有符號十進制(signed int)類型進行解析
// %p:內存數據按照指針意義進行解析
// 5.數組元素以及數組元素的地址:
// a[i]:a[i]表示數組元素的名稱,直接寫數組元素的名稱,相當于訪問該數組元素本身(數據)
// 好比叫一個人的名字,目的就是為了這個人知道
// &a[i]:&表示根據變量的名稱(內存實體)獲取該變量的地址
// 變量的名稱:其實就是內存實體的別名(區分:(變量:內存實體)-->(變量名稱:變量別名))
// 統稱:變量(統一)-->具稱:變量別名(唯一)
// 說明:中括號"[]"的優先級高于取內存實體地址符"&"的優先級
int main02(void)
{//0,1,2,3,4int a[5] = { 1,2,3,4,5 };//a:數組名稱,a代表該數組的內存首地址printf("%d \n", sizeof(a));//sizeof(a):用于獲取數組所占用的真實內存尺寸(字節大小)printf("%p \n", a);//數組的內存首地址for (int i = 0; i < 5; i++){printf("%d, %p \n", a[i], &a[i]);//i:索引;&:符號表示獲取變量的內存首地址}system("pause");
}//06.數組元素本身(內存實體)和數組元素地址(內存實體地址)
// 1.數組元素地址(內存實體地址)
// &a[i],a+i:數組默認從第0個開始進行索引劃分(數組元素(內存實體)的標識符:索引)
// 2.數組元素本身(內存實體):
// a[i],*(&a[i]),*(a+i)
int main03(void)
{//數組聲明語法:double a[10];數組元素的類型 數組整體的名稱[數組元素的個數];double a[10] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0 };printf("%d \n", sizeof(a));//10*8=80for (int i = 0; i < 10; i++){//&a[i], a + i;//代表數組第i個元素的內存實體地址,等價關系a+i(與類型密切相關)//以0作為開頭//a + (i - 1)*sizeof(double);//以1作為開頭//*號表示根據內存實體的地址獲取內存實體本身(數據內容)//a[i], *(&a[i]), *(a + i);//效果等價printf("%lf, %lf, %lf, %p, %p \n", a[i], *(&a[i]), *(a + i), &a[i], a + i);//下標,索引}system("pause");
} ///02.數組初始化語法.c
#include <stdio.h>
#include <stdlib.h>//01.數組的初始化方式:
// 標準方式:
// int a[5] = {1, 2, 3, 4, 5};
// 數組元素的類型 數組整體的名稱[數組元素的指明個數] = {靜態初始化的靜態數據};
// 簡化方式:
// itn a[] = {1, 2, 3, 4, 5};
// 注意事項:
// 1.C/C++當中的靜態數組必須進行靜態初始化才能進行使用,Java當中的靜態數組會進行默認初始化
// 大括號:{}就是表明靜態初始化
// 2.數組的聲明必須明確兩點:數組元素的數據類型+數組元素的元素個數-->才能確定數組整體尺寸(內存字節數)
// 3.賦值特點:
// (1).大括號這種靜態初始化方式,只能適用于聲明數組的狀態下(聲明并定義的情況之下)
// (2).統一賦值與指明賦值特點:
// 統一賦值:{0}
// 指明賦值:
// 完全賦值:
// {1, 2, 3, 4, 5}
// 前置局部:
// {1, 2, 3}-->后面默認被編譯器初始化為0,只有當前面進行了指明初始化的情況,后面才會進行默認初始化為0的操作
// 4.訪問特點:
// 訪問數組整體的內部某個元素本身(內存實體本身),不會出錯
// 訪問數組整體的外部某個元素本身(內存實體本身),可能出錯,可能不出錯(關鍵是看系統是否為該內存實體分配了使用權限)
int main04(void)
{//int a[10] = { 0 };//C/C++當中的數組必須進行初始化//int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };//明確數組初始化元素個數,可以省略數組元素個數的聲明//int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };//數組初始化不允許越界//int a[10] = { 1, 2, 3, 4 };//默認沒有初始化值的數組元素都將會被默認的初始化為0int a[5] = { 0 };//數組必須明確其元素個數for (int i = 0; i < 10; i++){//注意不存在長度部分的數據將會是無法預料的值,5之后的數據可能會出現問題printf("%d \n", a[i]);}system("pause");
}//02.數組名稱的操作:
// 1.任何指針進行加法,乘法,除法都沒有任何實際意義
// 2.在同一個數組當中的不同內存實體的內存地址進行
// 減法運算具備實際意義,用于獲取兩個數組元素之間的元素個數差值
// 3.C語言的常規數組不能進行整體操作,元素本身(內存實體)可以進行整體操作
// 4.C語言的特殊素組(字符數組),如果以'\0'結尾,那么就是一個正常的字符串模擬
// 字符串結尾標識符必須是'\0'(字符\0)-->0或者'\0'都一樣
// 字符:'\0'-->ASCII:0-->以及關鍵字NULL
int main05(void)
{int a[5] = { 1, 2, 3, 4, 5 };int b[5] = { 2, 3, 4, 5, 6 };//a = b;//數組名稱:標識數組整體的內存空間,數組名稱是一個常量指針,不可以直接進行修改//a[1];//訪問整體數組a當中的第1個元素所對應的內存實體(數據本身)//a + b;//C語言當中的普通數組不可以進行批量草最,只能針對于某一個元素進行批量操作//a < b;char str[5] = { 'c', 'a', 'l', 'c', NULL }; printf("%s \n", str);system("pause");
} 程序片段(02):01.數組.c+02.數組實戰.c
內容概要:數組實戰
///01.數組.c
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>//01.數組越界問題分析;
// 1.采用數組名稱訪問內存實體的時候:
// 如果該內存實體位于數組整體當中的某個部分,那么訪問正確
// 如果該內存實體位于數組整體外部的某個部分,那么訪問出錯
// 因為操作系統并沒有為當前程序當中的數組分配該整體數組外部的內存實體的訪問權限
// 2.C語言編譯器的特點所導致:
// 數組不越界一定不會出錯,數組越界可能會出錯(編譯通過但是運行不一定通過)
int main01(void)
{//數組越界不一定出錯,但是不越界一定不會發生內存訪問沖突int a[5] = { 1, 2, 3, 4, 5 };for (int i = 0; i < 10; ++i){printf("%d \n", a[i]);//存在越界的情況,但是C語言的編譯器不一定會進行報錯}//當采用數組方式訪問到別處內存地址所對應的內存實體(數據本身)的時候,可能會出現報錯的情況:// 因為該內存地址在賦值之前就已經具備了一定內存實體(數據本身),不允許緊急性數組操作// 因為操作系統并沒有為本程序分配該內存地址的使用權限a[102389898] = 1;system("pause");
}int main02(void)
{int a[10] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };for (int i = 9; i > -1; --i){//逆序輸出數組內存實體(數據本身)printf("%d \n", a[i]);}system("pause");
}int main03(void)
{int a[100] = { 0 };time_t te = 0;//unsigned int seed = (unsigned int)(time(&te));//獲取隨機數種子//srand(seed);//種植隨機數種子srand((unsigned int)(time(&te)));for (int i = 0; i < 100; i++){//循環初始化方式(隨機數)a[i] = rand() % 300;printf("%d \n", a[i]);}int num = 0;scanf("%d", &num);int flag = 0;//假定找不到-->標識多數情況for (int i = 0; i < 100; ++i)if (a[num] == num){flag = 1;//標識找到-->只要存在情況break;}if (flag)printf("找到! \n");elseprintf("找不到! \n");system("pause");
} ///02.數組實戰.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>//01.最簡單,最無效率的極值獲取方式:
// 打擂算法:極值獲取以及極值在數組當中所對應的索引
int main04(void)
{time_t te = 0;srand((unsigned int)(time(&te)));//獲取并終止隨機數種子int a[20] = { 0 };for (int i = 0; i < 20; ++i){a[i] = rand() % 300;//通過隨機數進行數組的賦值printf("%d \n", a[i]);}int minValue = a[0];for (int i = 1; i < 20; ++i) //打擂算法:獲取極小值if (minValue > a[i])minValue = a[i];int maxValue = a[0];for (int i = 1; i < 20; i++)//打擂算法:獲取極大值if (maxValue < a[i])maxValue = a[i];int minIndex1 = 0;int minValue1 = a[0];for (int i = 1; i < 20; i++)//打累算法:獲取極小值以及極小值在數組當中所對應的索引if (minValue1 > a[i]){minIndex1 = i;minValue1 = a[i];}printf("minIndex1 = %d, minValue1 = %d \n", minIndex1, minValue1);system("pause");
}//02.最簡單的排序算法:
// 1.選擇排序算法
// 2.時空復雜度分析:
// 時間復雜度:n平方
// 空間復雜度:1
#define EN 20
int a[EN];//C語言全局變量默認被初始化為0
int main05(void)
{time_t te = 0;srand((unsigned int)(time(&te)));//獲取并種植隨機數種子for (int i = 0; i < 20; ++i){a[i] = rand() % 300;//給數組進行進行隨機數賦值printf("%d \n", a[i]);}printf("\n");int gtIndex = 0;for (int i = 0; i < EN - 1; ++i){gtIndex = i;for (int j = i + 1; j < EN; ++j)if (a[gtIndex] < a[j])gtIndex = j;if (i != gtIndex){a[i] = a[i] ^ a[gtIndex];a[gtIndex] = a[i] ^ a[gtIndex];a[i] = a[i] ^ a[gtIndex];}}for (int i = 0; i < 20; ++i){printf("%d \n", a[i]);}system("pause");
} 程序片段(03):main.c
內容概要:GccArray
#include <stdio.h>
#include <stdlib.h>int main()
{int num=10;scanf("%d",&num);int a[num];//GCC支持動態分配數組:因此數組的元素個數指定可以采取變量,偽常量,真常量//動態分配,運行的時候return 0;
}
程序片段(04):冒泡排序.c
內容概要:冒泡排序法
#include <stdio.h>
#include <stdlib.h>int main01(void)
{int intArr[10] = { 3, 5, 18, 9, 23, 5, 2, 1, 0, 2 };for (int i = 0; i < 10 - 1; ++i){//冒泡法求最大值:兩兩臨近的數據進行比較if (intArr[i] > intArr[i + 1]){intArr[i] = intArr[i] ^ intArr[i + 1];intArr[i + 1] = intArr[i] ^ intArr[i + 1];intArr[i] = intArr[i] ^ intArr[i + 1];}}printf("maxValue = %d \n", intArr[9]);system("pause");
}int main02(void)
{int intArr[10] = { 3, 5, 18, 9, 23, 5, 2, 1, 0, 2 };for (int i = 0; i < 10 - 1; ++i)//外層循環,每完成一次循環,就有一個最值沉底{//冒泡法實現排序:重復進行相鄰的兩個數據比較for (int j = 0; j < 10 - 1 - i; ++j)//沉底的次數,決定冒到了那里{if (intArr[j] > intArr[j + 1])//沉底{intArr[j] = intArr[j] ^ intArr[j + 1];intArr[j + 1] = intArr[j] ^ intArr[j + 1];intArr[j] = intArr[j] ^ intArr[j + 1];}}}for (int i = 0; i < 10; ++i){printf("%d \n", intArr[i]);}system("pause");
} 程序片段(05):斐波那契.c
內容概要:斐波那契數組法
#include <stdio.h>
#include <stdlib.h>//01.斐波那契數列:
// 1.循環實現
// 2.遞歸實現
// 3.(循環+棧)實現
//02.數組的使用特點:
// 模擬棧這種數據結構
// 先進后出
// 模擬隊列這種數據結構
// 先進先出
//03.如何進行遞歸加速?
// 遞歸-->循環+棧:可以實現遞歸加速
//04.三種實現斐波那契數列方式的速度問題:
// (循環+棧)>循環>遞歸
int fibonacciLoop(int nItem)
{//循環實現:if (1 == nItem || 2 == nItem)return 1;int temp1 = 1;int temp2 = 1;int nItemValue = 0;//初始化一個常數,效率更高for (int i = 2; i < nItem; ++i){nItemValue = temp1 + temp2;//存儲推理結果temp1 = temp2;//數據往前推進temp2 = nItemValue;}return nItemValue;
}int fibonacciRecursion(int nItem)
{//遞歸實現:if (1 == nItem || 2 == nItem)return 1;return fibonacciRecursion(nItem - 1) + fibonacciRecursion(nItem - 2);//關系表達式
}int fibonacciLoopStack(int nItem)
{//(循環+棧)實現:int intArr[64] = { 0 };intArr[0] = 1;intArr[1] = 1;for (int i = 2; i < nItem; ++i)//注意數組存儲特點{intArr[i] = intArr[i - 1] + intArr[i - 2];}return intArr[nItem - 1];
}int main01(void)
{printf("loopResult = %d \n", fibonacciLoop(40));printf("recursionResult = %d \n", fibonacciRecursion(40));printf("loopStackResult = %d \n", fibonacciLoopStack(40));system("pause");
} 程序片段(06):迷宮1.c
內容概要:迷宮模擬
#include <stdio.h>
#include <stdlib.h>void showIntArr(int intArr[10][10])
{//顯示二維數組printf("------------------------------ \n");for (int i = 0; i < 10; ++i){for (int j = 0; j < 10; ++j){printf("%3d", intArr[i][j]);}printf("\n");}printf("------------------------------ \n");
}//01.數組數據的存儲特點:
// 1.所有數組的數據在內存當中的存儲方式都是線性的
// 2.顯式的結果不同是由于不同維度的數組對內存當中的數據的解析方式不同
int main01(void)
{int intArr[10][10] = {//二維數組的圖形化初始化方式:將二維數組當做一維數組進行看待,該一維數組當中的每個元素就是一行的數據信息{0, 0, 0, 2, 0, 0, 0, 0, 0, 0},{0, 0, 2, 0, 0, 0, 0, 0, 0, 0},{0, 0, 2, 2, 2, 0, 0, 0, 0, 0},{0, 0, 0, 0, 2, 0, 0, 0, 0, 0},{0, 0, 0, 0, 2, 0, 0, 0, 0, 0},{0, 2, 2, 0, 0, 0, 0, 0, 0, 0},{2, 0, 0, 0, 0, 0, 0, 2, 0, 2},{0, 2, 2, 0, 0, 0, 2, 2, 0, 0},{2, 0, 0, 2, 0, 2, 0, 0, 0, 0},{0, 0, 0, 0, 0, 2, 0, 2, 0, 0}};showIntArr(intArr);int px = 0, py = 0;//點坐標(默認:左上角(0,0)點)intArr[px][py] = 1;//根據點坐標修改棋盤上對應點坐標的數據實體(二維平面的數據實體修改為0)showIntArr(intArr);char ch = '\0';while (1){ch = getchar();getchar();//吸收Enter鍵-->'\n'-->'\r\n':Win解析switch (ch){case 'w'://按鍵控制if (px - 1 >= 0 && intArr[px][py] != 2){intArr[px][py] = intArr[px][py] ^ intArr[px - 1][py];intArr[px - 1][py] = intArr[px][py] ^ intArr[px - 1][py];intArr[px][py] = intArr[px][py] ^ intArr[px - 1][py];--px;}break;case 's':if (px + 1 <= 9 && intArr[px + 1][py] != 2){intArr[px][py] = intArr[px][py] ^ intArr[px + 1][py];intArr[px + 1][py] = intArr[px][py] ^ intArr[px + 1][py];intArr[px][py] = intArr[px][py] ^ intArr[px + 1][py];++px;}break;case 'a':if (0 <= py - 1 && 2 != intArr[px][py - 1]){intArr[px][py] = intArr[px][py] ^ intArr[px][py - 1];intArr[px][py - 1] = intArr[px][py] ^ intArr[px][py - 1];intArr[px][py] = intArr[px][py] ^ intArr[px][py - 1];--py;}break;case 'd':if (9 >= intArr[px][py + 1] && 2 != intArr[px][py + 1]){intArr[px][py] = intArr[px][py] ^ intArr[px][py + 1];intArr[px][py + 1] = intArr[px][py] ^ intArr[px][py + 1];intArr[px][py] = intArr[px][py] ^ intArr[px][py + 1];++py;}break;}showIntArr(intArr);}system("pause");
} 程序片段(07):二分查找法.c
內容概要:二分查找法以及拉格朗日插值查找
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>//01.二分查找法以及二分查找法的變形:
// 1.前提條件:待查找的數組當中的數據必須有序
// 最好是順序排列的(從小到大進行排列)
// 2.二分查找以及拉格朗日查找:
// 拉格朗日查找用于二分查找的加速模式
#define N 1024
int binarySearch(int intArr[N], int value)
{//二分查找法int minIndex = 0;int maxIndex = N - 1;int midIndex = 0;while (minIndex <= maxIndex){midIndex = (minIndex + maxIndex) / 2;if (value == intArr[midIndex])return midIndex;else if (value < intArr[midIndex])maxIndex = --midIndex;elseminIndex = ++minIndex;}return -1;
}int lagrangeSearch(int intArr[N], int value)
{//拉格朗日查找法int minIndex = 0;int maxIndex = N - 1;//int midIndex = 0;int tempIndex = 0;while (minIndex <= maxIndex){//midIndex = (minIndex + maxIndex) / 2;//midIndex = minIndex + (maxIndex - minIndex) / 2;tempIndex = minIndex + (value - intArr[minIndex]) / (intArr[maxIndex] - intArr[minIndex]);//二分查找加速if (value == intArr[tempIndex])return tempIndex;else if (value < intArr[tempIndex])maxIndex = --tempIndex;elseminIndex = ++tempIndex;}return -1;
}int main01(void)
{int intArr[1024] = { 0 };for (int i = 0; i < 1024; ++i)intArr[i] = i;int value = 0;scanf("%d", &value);printf("valueIndex = %d \n", binarySearch(intArr, value));printf("valueIndex = %d \n", lagrangeSearch(intArr, value));system("pause");
} 程序片段(08):插入排序法.c
內容概要:插入排序法
#include <stdio.h>
#include <stdlib.h>int main01(void)
{//插值法也要求數據必須有序int intArr[10] = { 1, 2, 3, 4, 6, 7, 8, 9, 10, 5 };int tempIndex = 9;int tempValue = intArr[9];while (tempIndex > 0 && intArr[tempIndex - 1] > tempValue)//從后往前進行插值{ //tempIndex>0:由于要讓索引-1,但是索引-1之后必須>=0因此索引必須>=1//當此循環退出的時候,退出時所在的索引其實就是剛好需要進行插值的索引位置intArr[tempIndex] = intArr[tempIndex - 1];--tempIndex;}intArr[tempIndex] = tempValue;for (int i = 0; i < 10; ++i)printf("%3d", intArr[i]);system("pause");
}#define EN 10
void insertSort(int intArr[EN])
{int tempIndex = 0;int tempValue = 0;//01.插值排序法說明:// int i = 1:// 當元素個數為1的時候,不需要插值排序算法// 從1開始才能便于進行插值操作intArr[index-1]=intArr[index]// i < 10:// 從第一個元素開始,到最后一個元素都需要進行插值排序檢測// 注:忽略掉單個元素的數組,因為單個元素不存在插值排序// tempIndex > 0:(可能插值移位的最大范圍)// 能夠進行插值移位的前提// intArr[tempIndex - 1] > tempValue:(可能插值移位的最小范圍)// 只要當前索引的前一個索引所對應的值大于待插入的值// 就有必要執行插入操作for (int i = 1; i < 10; ++i){tempIndex = i;tempValue = intArr[i];while (tempIndex > 0 && intArr[tempIndex - 1] > tempValue){intArr[tempIndex] = intArr[tempIndex - 1];--tempIndex;}intArr[tempIndex] = tempValue;}
}int main02(void)
{int intArr[EN] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 10 };insertSort(intArr);for (int i = 0; i < EN; ++i){printf("%3d", intArr[i]);}system("pause");
} 程序片段(09):開房.c
內容概要:開房數據檢索-硬盤模式
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>char resourcesPath[256] = "D:\\Resource\\TestData\\DB\\KaiFang.txt";
char targetWritePath[256] = { 0 };void selectResultWriteToTargetFile(char nameStr[256])
{sprintf(targetWritePath, "D:\\Resource\\TestData\\Test\\%s.txt", nameStr);FILE *frp = fopen(resourcesPath, "r");//以讀取模式打開一個文件(硬盤直接讀取模式)FILE *fwp = fopen(targetWritePath, "w");//以寫入模式打開一個文件(硬盤直接寫入模式)if (NULL == frp && NULL == fwp){printf("建立文件指針失敗! \n");return;}while(!feof(frp))//feof();到了文件讀取的末尾返回真,沒有到文件讀取的末尾返回假{//只要沒有到達文件讀取的末尾,就繼續進行硬盤文件讀取操作char readStr[1024] = { 0 };fgets(readStr, 1024, frp);//硬盤模式讀取一行數據(以換行符作為讀取模式結束,并且長度僅限為1024)讀取條件限制char *tempStr = strstr(readStr, nameStr);if (NULL != tempStr){puts(readStr);//打印檢索到的數據行fputs(readStr, fwp);//硬盤模式寫入到指定文件}}fclose(fwp);//關閉文件寫入流fclose(frp);//關閉文件讀取流
}int main01(void)
{char nameStr[256] = { 0 };scanf("%s", nameStr);printf("您要查詢人的姓名是:%s \n", nameStr);time_t start = 0, end = 0;time(&start);selectResultWriteToTargetFile(nameStr);time(&end);printf("查詢總計話費了%lf秒 \n", difftime(end, start));system(targetWritePath);system("pause");
} 程序片段(10):二維數組.c
內容概要:二維數組
#include <stdio.h>
#include <stdlib.h>//01.二維數組:
// 1.二維數組的內存存儲原理:
// 所有數組,無論一維數組,二維數組,多維數組,在內存當中的
// 存儲實質都是采取的連續存儲方式
// 2.二維數組的規律賦值方式:
// 先進行行遍歷,在進行列遍歷,再逐個進行逐個數組元素的具體賦值操作
// 3.如何求取任何數組的內存尺寸?
// 都是采用sizeof();關鍵字進行的求取
int main01(void)
{int a[5][5];//1, 2, 3, 4, 5, 6, 7, 8, 9, 10:總共25個數組元素printf("%d \n", sizeof(a));//sizeof(數組名);-->求取數組整體的內存尺寸5*5*4printf("%p \n", a);int num = 1;for (int i = 0; i < 5; ++i){for (int j = 0; j < 5; ++j){//a[i][j] = num;//++num;//printf("%4d", a[i][j]);printf("%4d", a[i][j] = num++);//復合語句}}system("pause");
}//02.二維數組知識詳解:
// 1.初始化方式:
// 統一初始化:
// int a[5][4] = {0};-->巧用0
// 前置初始化:
// int a[5][4] = {1}-->特用除0以外的數字
// 注:
// 1.統一初始化方式的實質還是前置初始化方式,由于采用特殊的數字
// 0進行初始化,所以整體被統一的初始化為了0
// 2.所有數組的初始化方式特點:
// 只要數組當中前置元素有數字前置初始化,那么后面的數組元素
// 本身都會被默認的初始化為0
// 2.多維數組的特殊初始化方式:
// 多維數組轉化為低維數組進行初始化
// int a[5][4] = {
// {1, 2},
// {1, 2, 3}
// };
// 3.確定數組內存尺寸的兩大要素:
// 數組元素個數+數組元素尺寸
// 注:維度的省略情況分析:自動推演
// 一維數組的一維可以省略
// 二維數組的一維不可以省略
// 三維數組的二維不可以省略
int main02(void)
{//int a[5][4] = { 1 };//全部初始化為0//printf("%p \n", a);//int a[5][4] = { 1, 2, 3, 4, 5 };//數組的前面賦值,后面賦值為0,默認是一行一行的進行賦值操作//int a[5][4] = { {1, 2, 3, 4}, {1, 2} };//二維數組的初始化方式//int a[5][4] = {0};//全部初始化為0int a[5][4];//解釋:5個一維數組,每個一維數組當中存儲有4個數組元素int b[2][4] = { {1,2},{3,4} };//第一個名曲有幾個一維數組,可以進行忽略//行坐標可以進行忽略,但是列坐標不可以進行忽略int num = 1;for (int i = 0; i < 2; ++i){for (int j = 0; j < 4; ++j){b[i][j] = num++;}}printf("\n\n");for (int i = 0; i < 2; ++i){for (int j = 0; j < 4; ++j){printf("%4d", b[i][j]);}}system("pause");
}//03.二維數組的線性初始化方式:
// 奧數規律方式
// 元素個數+求模(變化慢)+求余(變化快)+被除數是(列數)
int mai03n(void)
{int intArrArr[3][4];//規律初始化方式:// 00 0 01 1 02 2 03 3// 10 4 11 5 12 6 13 7// 20 8 21 9 22 10 23 11for (int i = 0; i < 12; ++i)//i:決定元素個數{intArrArr[i / 4][i % 4] = i;//行:變化慢;列:變化快}for (int i = 0; i < 3; ++i){for (int j = 0; j < 4; ++j){printf("%3d", intArrArr[i][j]);}printf("\n");}system("pause");
} 程序片段(11):迷宮初步.c+迷宮進階.c
內容概要:迷宮AI
///迷宮初步.c
#include <stdio.h>
#include <stdlib.h>//01.關于維度與數組的聯系:
// 零維度:點
// 1.數組元素
// 2.沒有方向
// 一維度:線
// 1.一維數組
// 2.向右方向
// 二維度:面
// 1.二維數組
// 2.上下左右
// 三維度:立體
// 1.三維數組
// 2.上下左右前后
// 多維度:慢慢想
// 1.高維數組
// 2.慢慢想
// 注:時間(變化)+空間(三維)
//02.所有數組的內存存儲特點:
// 都是采取線性的初始方式,也就是連續存儲的方式
// 只是由于計算機對于數組的解析方式的不同,所以產生了不同的維度效果
//03.迷宮矩陣的組成特點分析:
// 1.二維平面的迷宮矩陣由二維整型數組進行模擬
// 2.該二微整型數組的組成元素特點分析:
// 數字0:代表通道
// 數字2:代表墻壁
// 數字1:代表位置
// 3.移動點和結束點模擬移動:
// 移動點:(startPointX, startPointY);
// 結束點:(endPointX, endPointY);
int intArrArrMaze[5][5] = {{ 0, 0, 2, 2, 2 },{ 2, 0, 0, 0, 2 },{ 2, 0, 0, 0, 2 },{ 2, 0, 0, 0, 2 },{ 2, 0, 0, 0, 0 },
};
int endPointX = 4, endPointY = 4;//終止點int visitMaze(int startPointX, int startPointY);int main(void)
{printf("顯示迷宮 \n");printf("-------------------------------------- \n");for (int i = 0; i < 5; ++i){for (int j = 0; j < 5; ++j){printf("%3d", intArrArrMaze[i][j]);}printf("\n");}int startPointX = 0, startPointY = 0;//起始點if (0 == visitMaze(startPointX, startPointY)){printf("迷宮沒有出口 \n");}else{printf("顯示路徑 \n");for (int i = 0; i < 5; ++i){for (int j = 0; j < 5; ++j){if (2 == intArrArrMaze[i][j])printf("█");else if (1 == intArrArrMaze[i][j])printf("◇");elseprintf(" ");}printf("\n");}}system("pause");
}//04.該函數的作用功能作用分析:
// 1.函數整體作用:
// 通過遞歸調用方式判定迷宮是否有出口?
// 如果走到終點,那么就含有出口;如果沒能走到出口,那么就沒有出口!
// 2.函數局部作用:
// 每走動一次,都需要判定是否到達迷宮終點
// 3.參數說明:
// 形參值:
// 整體意義:起始點
// 局部意義:將要走動的點-->試探點
// 返回值:
// 整體意義:是否能夠走出迷宮
// 局部意義:判斷是否完成了一條路線
int visitMaze(int startPointX, int startPointY)
{int success = 0;//標識迷宮是否完成走出狀態int movePointX = startPointX;//通過起始點初始化移動點int movePointY = startPointY;intArrArrMaze[movePointX][movePointY] = 3;//標識該點的起始狀態:if (endPointX == movePointX && endPointY == movePointY)return success = 1;//標識成功的走出狀態if (1 != success && 5 > movePointY + 1 && 2 > intArrArrMaze[movePointX][movePointY + 1]) visitMaze(movePointX, movePointY + 1);if (1 != success && 5 > movePointX + 1 && 2 > intArrArrMaze[movePointX + 1][movePointY]) visitMaze(movePointX + 1, movePointY);if (1 != success && -1 < movePointY - 1 && 2 > intArrArrMaze[movePointX][movePointY - 1]) visitMaze(movePointX, movePointY - 1);if (1 != success && -1 < movePointY - 1 && 2 > intArrArrMaze[movePointX - 1][movePointY]) visitMaze(movePointX- 1, movePointY);if (1 != success)//標識改點的回溯狀態:該點走過,但是沒有走成功,因此將該點重新值置為0intArrArrMaze[movePointX][movePointY] = 0;return success;
} ///迷宮進階.c
#include <stdio.h>
#include <stdlib.h>//數據層(Data):存儲數據
int intArrArrMazeY[10][10] = {//原始迷宮{ 1, 0, 2, 0, 0, 0, 0, 0, 0, 0 },{ 0, 0, 2, 2, 0, 0, 0, 0, 0, 0 },{ 0, 0, 0, 0, 2, 0, 0, 0, 0, 0 },{ 2, 2, 2, 0, 0, 2, 0, 0, 0, 0 },{ 0, 0, 2, 0, 0, 0, 2, 0, 2, 2 },{ 0, 0, 2, 0, 0, 0, 0, 0, 0, 0 },{ 0, 0, 0, 2, 0, 0, 0, 2, 0, 2 },{ 0, 0, 0, 0, 2, 0, 0, 2, 0, 0 },{ 0, 0, 0, 0, 0, 2, 0, 2, 2, 0 },{ 0, 0, 0, 0, 0, 0, 2, 2, 0, 0 }
};
int intArrArrMazeC[10][10] = {//測試迷宮{ 1, 0, 2, 0, 0, 0, 0, 0, 0, 0 },{ 0, 0, 2, 2, 0, 0, 0, 0, 0, 0 },{ 0, 0, 0, 0, 2, 0, 0, 0, 0, 0 },{ 2, 2, 2, 0, 0, 2, 0, 0, 0, 0 },{ 0, 0, 2, 0, 0, 0, 2, 0, 2, 2 },{ 0, 0, 2, 0, 0, 0, 0, 0, 0, 0 },{ 0, 0, 0, 2, 0, 0, 0, 2, 0, 2 },{ 0, 0, 0, 0, 2, 0, 0, 2, 0, 0 },{ 0, 0, 0, 0, 0, 2, 0, 2, 2, 0 },{ 0, 0, 0, 0, 0, 0, 2, 2, 0, 0 }
};
int endPointX = 9, endPointY = 9;
int countCiNum = 1;//視圖層(View):顯示數據
void showMaze(int intArrArrMaze[10][10])
{printf("%d------------------------------ \n", countCiNum++);for (int i = 0; i < 10; ++i){for (int j = 0; j < 10; ++j){printf("%2d", intArrArrMaze[i][j]);}printf("\n");}
}//控制層(Controller):數據操作
void operateMaze(char direction, int startPointX, int startPointY)
{switch (direction){case 'w':if (-1 < startPointX - 1 && 2 != intArrArrMazeC[startPointX - 1][startPointY]){intArrArrMazeC[startPointX][startPointY] = intArrArrMazeC[startPointX][startPointY] ^ intArrArrMazeC[startPointX - 1][startPointY];intArrArrMazeC[startPointX - 1][startPointY] = intArrArrMazeC[startPointX][startPointY] ^ intArrArrMazeC[startPointX - 1][startPointY];intArrArrMazeC[startPointX][startPointY] = intArrArrMazeC[startPointX][startPointY] ^ intArrArrMazeC[startPointX - 1][startPointY];}break; case 's':if (10 > startPointX + 1 && 2 != intArrArrMazeC[startPointX + 1][startPointY]){intArrArrMazeC[startPointX][startPointY] = intArrArrMazeC[startPointX][startPointY] ^ intArrArrMazeC[startPointX + 1][startPointY];intArrArrMazeC[startPointX + 1][startPointY] = intArrArrMazeC[startPointX][startPointY] ^ intArrArrMazeC[startPointX + 1][startPointY];intArrArrMazeC[startPointX][startPointY] = intArrArrMazeC[startPointX][startPointY] ^ intArrArrMazeC[startPointX + 1][startPointY];}break;case 'a':if (-1 < startPointY - 1 && 2 != intArrArrMazeC[startPointX][startPointY - 1]){intArrArrMazeC[startPointX][startPointY] = intArrArrMazeC[startPointX][startPointY] ^ intArrArrMazeC[startPointX][startPointY - 1];intArrArrMazeC[startPointX][startPointY - 1] = intArrArrMazeC[startPointX][startPointY] ^ intArrArrMazeC[startPointX][startPointY - 1];intArrArrMazeC[startPointX][startPointY] = intArrArrMazeC[startPointX][startPointY] ^ intArrArrMazeC[startPointX][startPointY - 1];}break;case 'd':if (10 > startPointY + 1 && 2 != intArrArrMazeC[startPointX][startPointY + 1]){intArrArrMazeC[startPointX][startPointY] = intArrArrMazeC[startPointX][startPointY] ^ intArrArrMazeC[startPointX][startPointY + 1];intArrArrMazeC[startPointX][startPointY + 1] = intArrArrMazeC[startPointX][startPointY] ^ intArrArrMazeC[startPointX][startPointY + 1];intArrArrMazeC[startPointX][startPointY] = intArrArrMazeC[startPointX][startPointY] ^ intArrArrMazeC[startPointX][startPointY + 1];}break;default :break;}showMaze(intArrArrMazeC);
}//業務層(Service/AI層):人工智能
// 組成特點分析:
// 返回值:int
// 整體意義:迷宮是否能夠走通
// 局部意義:沒有完成一條通路,就繼續往下走
// 不斷的進行壓棧,壓到樹狀遞歸的底部
// 如果不行:如果該路不通,就進行回溯釋放函數所占用的棧內存(返回值無意義)
// 如果能行:如果該路暢通,就進行回溯釋放函數做占用的棧內存(返回值有意義)
// 形參值:
// int intArrArrMaze[10][10]:
// 整體意義:待測試的迷宮數據
// 局部意義:每次迷宮的下一步,所依賴的上一步迷宮數據布局
// int startPointX, int startPointY:
// 整體意義:就是迷宮的起始點
// 局部意義:就是迷宮每次要試探的下一點
int mazeAI(int intArrArrMaze[10][10], int startPointX, int startPointY)
{int successFlag = 0;int movePointX = startPointX; //測試假定起始點的正確性int movePointY = startPointY;intArrArrMaze[startPointX][startPointY] = 3;//試探迷宮走步(測試點成功走出)-->假定起點成功if (endPointX == movePointX && endPointY == movePointY)//當前待移動的點所在的位置{printf("小伙子恭喜走出來了! \n");return successFlag = 1;}//右下左上// 1 != successFlag:// 這條語句表明還沒有形成完整的通路,因此急需尋找,最終尋找到的通路// 一定是每一個遞歸函數都返回1的情況// 2 > intArrArrMaze[movePointX][movePointY + 1]:// 這條語句的作用既可以排除掉墻壁點,也可以排除走過點if (1 != successFlag && 10 > movePointY + 1 && 2 > intArrArrMaze[movePointX][movePointY + 1]) mazeAI(intArrArrMaze, movePointX, movePointY + 1);if (1 != successFlag && 10 > movePointX + 1 && 2 > intArrArrMaze[movePointX + 1][movePointY]) mazeAI(intArrArrMaze, movePointX + 1, movePointY);if (1 != successFlag && -1 < movePointY - 1 && 2 > intArrArrMaze[movePointX][movePointY - 1]) mazeAI(intArrArrMaze, movePointX, movePointY - 1);if (1 != successFlag && -1 < movePointX - 1 && 2 > intArrArrMaze[movePointX - 1][movePointY]) mazeAI(intArrArrMaze, movePointX - 1, movePointY);if (0 == successFlag)//根據樹狀遞歸,遞歸到樹狀的根部返回情況決定當前路線是否通路(暢通|不暢通)-->完整路線intArrArrMaze[startPointX][startPointY] = 0;//試探迷宮回溯(測試點失敗走回)-->假定起點失敗return successFlag;
}void AIUnitTest(int intArrArrMaze[10][10], int startPointX, int startPointY)
{int movePointX = startPointX;int movePointY = startPointY;while (endPointX != movePointX || endPointY != movePointY){if (10 > movePointY + 1 && 3 == intArrArrMaze[movePointX][movePointY + 1]){intArrArrMaze[movePointX][movePointY + 1] = 0;operateMaze('d', movePointX, movePointY + 1);}if (10 > movePointX + 1 && 3 == intArrArrMaze[movePointX + 1][movePointY]){intArrArrMaze[movePointX + 1][movePointY] = 0;operateMaze('s', movePointX + 1, movePointY);}if (-1 < movePointY - 1 && 3 == intArrArrMaze[movePointX][movePointY - 1]){intArrArrMaze[movePointX][movePointY - 1] = 0;operateMaze('a', movePointX, movePointY - 1);}if (-1 < movePointX - 1 && 3 == intArrArrMaze[movePointX - 1][movePointY]){intArrArrMaze[movePointX - 1][movePointY] = 0;operateMaze('d', movePointX - 1, movePointY);}}
}int main02(void)
{//showMaze(intArrArrMazeY);int successFlag = mazeAI(intArrArrMazeC, 0, 0);if (successFlag){printf("可以走出! \n");intArrArrMazeY[0][0] = 1;showMaze(intArrArrMazeY);}else{printf("不可以走出! \n");}system("pause");
}
轉載于:https://www.cnblogs.com/niulanshan/p/6174616.html
總結
以上是生活随笔為你收集整理的20160203.CCPP体系详解(0013天)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 天猫精灵多少钱啊?
- 下一篇: 耶稣十字架是谁画的呢?