指针的优点:
方便好用,可以有效的对变量进行底层操作,直接操作变量的地址。非常好用,使代码变的更简洁。
常用于:
参数传递,在子函数中,修改传递进来的参数的值(而不是他的拷贝的值),必须传递指针,还有引用。
动态内存分配,有时候我们不可能知道我们到底要多少个变量,这时候我们就需要来动态的创建变量,就需要指针。
设计数据结构,数据结构是离不开指针的,无论是链表,树还是图。
指针的初始化,如果定义了一个指针,但是没有初始化的话,那么该指针可能是任意值,所以没有初始化的指针是极为不安全的
①,数据传递时,如果数据块较大,这时候可以使用指针传递地址而不是实际数据,即提高了传输速度又节省了大量内存。
②,数据转换,利用指针灵活的类型转换,可以用来做数据类型转换
③,字符串指针,使用最方便切最常用的。
④,函数指针,可以用在大量分支处理的实例中,建立一个函数指针数据,进行散转。
⑤,在数据结构中,链表,树,图都离不开指针。
C++中字符串和字符数组的区别
字符串可以用字符数组与字符串变量两种方式来存储,效果类似。
一、用字符数组来存储字符串:
char st1[100],st2[100] ; //字符数组说明
cin>>st1>>st2;
long a,b;
输入:hello,
则st1={‘h’,’e’,’l’,’l’,’o’,’,’,’\0’}
st2={‘w’,’o’,’r’,’l’,’d’,’\0}
字符’\0’为字符串结束标志
1. 字符数组长度
2. 字符数组比较
3. 连接字符数组
4. 替换
5. 其他函数
strchr(st1,ch) //ch为要找的字符。如strchr(st1,’e’);会截取出st1中以字母’e’开头的字符串,要用string类型的来存储,如string c1; c1=strchr(st1,’e’); 则c1为”ello”
二、用字符串来存储字符串
string str1,str2; cin>>str1>>str2;
//如输入“hello,
可直接赋值: str1=str2;
1. 字符串长度
2. 字符串比较
3. 连接
4. 字符串提取
5. 字符串搜索
6. 插入字符串
7. 替换字符串
8. 删除字符串
9. 交换字符串
注意:1.要包含头文件#include<cstring>
2.在有些场合下用字符数组char st1[100]比string st2还好用些,可根据具体情况作不同选择。
3.在读入一个含有空格的字符串时用cin是不行的(cin读字符串或字符数组时,自动以空格或回车作为分格符
字符串数组和指针的初始化的区别:
char amessage[] = "now is the time"; /* an array */
char *pmessage = "now is the time"; /* a pointer */
数组的内容是可变的,但是地址是始终不变的;指针p**中的内容是不可变的(不能被修改,是常量),但地址可变。
char astr[]="aaa"//这是个字符数组,只含有3个字符
char *pstr="aaa"//这是个字符串,含有4个字符,3个字符加一个'\0'
输出的结果strlen()长度都是3,strlen()计算字符串的长度,忽略结束符'\0'
①,字符串要比字符数组多一个空间,用来存放结束符'\0'
②,字符数组是不用存放\0的,所以分配的字符位数,只要strlen(p)就行,不用加1.
用字符数组,和字符指针变量,都可以实现字符串的存储和运算。
区别:1,字符串指针变量本身是一个变量,用于存放字符串的首地址,而字符串本身也是存放在以该首地址为首的一块连续的内存空间中,并以'\0'作为串的结束。字符数组由若干个数组元素组成,可以用来存放整个字符串。
字符串类型:
使用string类,必须包含头文件,<string>
string st("aaa")
返回长度:st.size()
string st2
坚持是否为空:st2.empty()
复制字符串: st2(st)
st2=st
比较是否相等:if(st2==st)
将两个字符串连接成一个字符串:string st3=st2+st1;
st1+=st2;直接加到第一个上
C常用字符串函数:
str系列
①char * strtok(char * s,const char *delim)
分解字符串为一组标记串。s为要分解的字符串,delim为分隔符字符串。
第一次调用时,strtok必须给与参数s字符串,往后的调用则将参数置换成NULL。每次调用成功则返回被分割成 片段的指针。当没有被分割的串时候返回NULL.
②char * strstr(const char * str1,const char *str2)
从字符串str1中,寻找str2第一次出现的位置,不比较结束符NULL,没有找到则返回NULL
③char * strchr(const char *str,char ch)
查找字符串str中首次出现字符ch的位置。返回首次出现ch位置的指针,如果str中不存在ch,则返回NULL。
④char * strcpy(char * dest,const char *src)
把src所指由NULL结束的字符串复制到dest所指的数组中。src和dest所指内存不能重叠,且dest有足够的空间来容纳src的字符串。返回指向dest结尾处字符串的指针。
⑤char * strcat(char * dest,const char *src)
功能:把src所指的字符串添加到dest结尾处。(覆盖dest结尾处的\0)并添加新的\0
说明:src和dest所指内吋区域不可重叠,切dest必须有足够的空间来容纳src的字符串。返回指向dest的指针。
⑥int strcmp(const char * str1,const char * str2)
功能:比较字符串str1,和str2
当s1<s2时,返回<0.
s1=s2时,返回=0
s1>s2时,返回>0
7,size_t strlen(const char *str)
计算str的长度,不包括结束符NULL。
mem系列:
①void * memset(void * ptr,char value,size_t num)
功能:把ptr所指内存区域的前num个字节设置成字符value。返回指向ptr的指针,可用于变量的初始化等操作。
3.memcpy
void * memcpy ( void * destination, const void * source, size_t num );
类似 strncpy。区别:拷贝指定大小的内存数据,而不管内容(不限于字符串)。
关系数据库的几种设计范式介绍 1、第一范式(1NF) 在任何一个关系数据库中,第一范式(1NF)是对关系模式的基本要求,不满足第一范式(1NF)的数据库就不是关系数据库。 所谓第一范式(1NF)是指数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值,即实体中的某个属性不能有多个值或者不能有重复的属性。如果出现重复的属性,就可能需要定义一个新的实体,新的实体由重复的属性构成,新实体与原实体之间为一对多关系。在第一范式(1NF)中表的每一行只包含一个实例的信息。例如,对于图3-2 中的员工信息表,不能将员工信息都放在一列中显示,也不能将其中的两列或多列在一列中显示;员工信息表的每一行只表示一个员工的信息,一个员工的信息在表中只出现一次。简而言之,第一范式就是无重复的列。 2、第二范式(2NF) 第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。第二范式(2NF)要求数据库表中的每个实例或行必须可以被唯一地区分。为实现区分通常需要为表加上一个列,以存储各个实例的唯一标识。如图3-2 员工信息表中加上了员工编号(emp_id)列,因为每个员工的员工编号是唯一的,因此每个员工可以被唯一区分。这个唯一属性列被称为主关键字或主键、主码。 第二范式(2NF)要求实体的属性完全依赖于主关键字。所谓完全依赖是指不能存在仅依赖主关键字一部分的属性,如果存在,那么这个属性和主关键字的这一部分应该分离出来形成一个新的实体,新实体与原实体之间是一对多的关系。为实现区分通常需要为表加上一个列,以存储各个实例的唯一标识。简而言之,第二范式就是非主属性非部分依赖于主关键字。 3、第三范式(3NF) 满足第三范式(3NF)必须先满足第二范式(2NF)。简而言之,第三范式(3NF)要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。例如,存在一个部门信息表,其中每个部门有部门编号(dept_id)、部门名称、部门简介等信息。那么在图3-2的员工信息表中列出部门编号后就不能再将部门名称、部门简介等与部门有关的信息再加入员工信息表中。如果不存在部门信息表,则根据第三范式(3NF)也应该构建它,否则就会有大量的数据冗余。简而言之,第三范式就是属性不依赖于其它非主属性。