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.