1.segmentation fault(core dump)
遇到上述錯誤,網上說是內存訪問越界。不管怎麼說指針不簡單啊。
1.內存訪問越界
a) 由於使用錯誤的下標,導致數組訪問越界
b) 搜索字符串時,依靠字符串結束符來判斷字符串是否結束,但是字符串沒有正常的使用結束符
c) 使用strcpy, strcat, sprintf, strcmp, strcasecmp等字符串操作函數,將目標字符串讀/寫爆。應該使用strncpy, strlcpy, strncat, strlcat, snprintf, strncmp, strncasecmp等函數防止讀寫越界。
2 多線程程序使用了線程不安全的函數。
3 多線程讀寫的數據未加鎖保護。對於會被多個線程同時訪問的全局數據,應該注意加鎖保護,否則很容易造成core dump
4 非法指針
a) 使用空指針
b) 隨意使用指針轉換。一個指向一段內存的指針,除非確定這段內存原先就分配爲某種結構或類型,或者這種結構或類型的數組,否則不要將它轉換爲這種結構或類型的指針,而應該將這段內存拷貝到一個這種結構或類型中,再訪問這個結構或類型。這是因爲如果這段內存的開始地址不是按照這種結構或類型對齊的,那麼訪問它時就很容易因爲bus error而core dump.
5 堆棧溢出.不要使用大的局部變量(因爲局部變量都分配在棧上),這樣容易造成堆棧溢出,破壞系統的棧和堆結構,導致出現莫名其妙的錯誤。
準備有時間好好學習一下c的內存分配和指針。
2.使用printf()輸出時,最好帶上"\n"換行符,否則不容易觀察輸出
3.c 中的string
好吧,我之前不知道c中沒有string類型,c中string的實現使用char*,使用時加頭文件<string.h>;c++中有標準string庫,使用時加<string>,c和c++都搞混了。
4.隨機數
主要有srand()和rand()兩個函數,包含在頭文件<stdlib.h>
srand():void srand ( unsigned int seed );
用法:它需要提供一個種子,這個種子會對應一個隨機數,如果使用相同的種子後面的 rand() 函數會出現一樣的隨機數。爲了防止隨機數每次重複常常使用系統時間來初始化,即使用 time函數來獲得系統時間,它的返回值爲從 00:00:00 GMT, January 1, 1970 到現在所持續的秒數,然後將 time_t型數據轉化爲(unsigned)型再傳給 srand 函數,即: srand((unsigned) time(&t)) 還有一個經常用法,即: srand((unsigned) time(NULL)); 直接傳入一個空指針,因爲你的程序中往往並不需要經過參數獲得的 t 數據。srand((int)getpid()); 使用程序的ID (getpid()) 來作爲初始化種子,在同一個程序中這個種子是固定的。
rand():int rand ( void );
產生一個僞隨機數(根據 srand 初始的隨機數種子),範圍爲 0 - RAND_MAX。RAND_MAX 至少爲 32767。可通過取模來產生不同範圍的隨機數,如:
int value = rand() % (MAX + 1 - MIN) + MIN;
使用方法:
srand((unsigned)time(NULL));
rtemp = rand() % 40;
隨機獲取[0,40)的整數。
5.獲取當前時間,包含在頭文件<time.h>中
time_t now;
struct tm *target_time; //實例化tm指針
time ( &now ); //time函數讀取現在的時間(國際標準時間非北京時間),然後傳值給now
target_time = localtime ( &now ); //localtime函數把從time取得的時間now換算成你電腦中的時間(就是你設置的時區)
printf("Local time is %s/n",asctime(target_time)); //asctime函數把時間轉換成字符,通過printf()函數輸出
註釋:time_t是一個在time.h中定義好的結構體。而tm結構體的原形如下:
struct tm
{
int tm_sec;//seconds 0-61
int tm_min;//minutes 1-59
int tm_hour;//hours 0-23
int tm_mday;//day of the month 1-31
int tm_mon;//months since jan 0-11 //當前月份要+1
int tm_year;//years 距離1900年的年數,當前年份要+1
int tm_wday;//days since Sunday, 0-6
int tm_yday;//days since Jan 1, 0-365
int tm_isdst;//Daylight Saving time indicator
};
6.gets 和gets ,都是獲取輸入,但兩者是有區別的
從文件或者屏幕讀入數據保存到buf中最多讀取bufsize-1個字符遇到換行符和文件末尾則結束。返回buf,讀取失敗則返回NULL。
注意:fgets會將最後的換行符存儲到buf中。
gets(char *buf);讀取字符到buf中。不會讀取換行符。
7.清除屏幕字符的命令和函數:linux下:
命令:clear
函數:system("clear");
8.linux c 刪除已輸入字符:
printf("hello\b \b"): 輸出:hell
(以下轉載):
printf("\033[47;31mhello world\033[5m");
47是字背景顏色, 31是字體的顏色, hello world是字符串. 後面的\033[5m是控制碼.
顏色代碼:
QUOTE:
字背景顏色範圍: 40--49 字顏色: 30--39
40: 黑 30: 黑
41: 紅 31: 紅
42: 綠 32: 綠
43: 黃 33: 黃
44: 藍 34: 藍
45: 紫 35: 紫
46: 深綠 36: 深綠
47: 白色 37: 白色
ANSI控制碼:
QUOTE:
\033[0m 關閉所有屬性
\033[1m 設置高亮度
\03[4m 下劃線
\033[5m 閃爍
\033[7m 反顯
\033[8m 消隱
\033[30m -- \033[37m 設置前景色
\033[40m -- \033[47m 設置背景色
\033[nA 光標上移n行
\03[nB 光標下移n行
\033[nC 光標右移n行
\033[nD 光標左移n行
\033[y;xH設置光標位置
\033[2J 清屏
\033[K 清除從光標到行尾的內容
\033[s 保存光標位置
\033[u 恢復光標位置
\033[?25l 隱藏光標
\33[?25h 顯示光標
這樣, 在某些時候就可以實現動態的輸出.
9.
NULL:空指針,沒有分配內存
'\0':字符串結束符
' ':空格
NULL: 定義爲0或0L或(void *)0,用於指示一個指針值是空,即什麼都不指;
'\0': 用且只用字符串結束符;
NUL : 0x00,0值字符,可以用於結束ASCII字符串,和'\0'類似,但是在c/c++中沒有定義,如果要使用的話,需要自定義爲 #define NUL '\0';
EOF :通常定義爲-1, 文件結束符標誌,一般是ctrl+z.