实习整理(二)

先写下自己在准备过程中所整理的资料,当然,这些资料不一定对于每个人都有用,只是自己碰到了而已,写得有问题的请随时提出,以便改正。。。
1.C++中求字符串长度的函数为:
            string s;
            s.length();


2.C++中指针和数组的关系
    以字符数组为例,字符数组实质上就是字符串,可以用字符串直接赋值
    char s1[6]="abcde";//char s1[]={'a','b','c','d','e'};
    char *s2=0;//不指向任何对象的指针
    s2=s1;//数组名s1代表了数组的首地址,即s2=&s1[0];
    char s3=*s2;//将字符数组的首元素赋值给s3,即s3=s1[0];
    *(s2++)和*(++s2)的区别:
    若s2当前指向s1的第三个元素,则前者为取出第三个元素之后再指向第四个元素,后者为指针先往后移指向第四个元素,接着取出第四个元素
    *(s2++)和*s2++的区别:
    若s2当前指向s1的第三个元素,则前者为取出第三个元素,返回第三个元素值,之后再指向第四个元素, 后者为取出第三个元素,让该元素自加,返回自加的结果,指针仍指向第三个元素
    指针数组和数组指针的区别:
    前者的形式为:数据类型 * s4[长度]=......  
    char * s4[3];//定义一个长度为3的数组,数组的类型为字符指针, s4[0]=s1;//将s1的首地址赋值给指针数组的第一个元素
    后者的形式为:char * s5=s1;//指向数组的指针 或者为:char (* s4)[3]
    void * s6;//可以指向任何数据类型的指针  s6=s1....
数组名不能进行赋值运算
此外:int a[4]={1,2,3,4}
a的类型:int *
&a的类型:int (*) [4]
int (* p1)=&a  int * p2=a;
二维数组也可以相似理解,同时指向数组的指针指的是指向整个数组元素的指针,而不是数组中单个元素的指针
注意:指针最容易发生内存泄露,即内存没有任何指针指向,因此在编程时要注意,我觉得在使用指针时为了避免产生混乱,最好在纸上将指针的指向情况画出来


跳跃下:重写 和 重载
重写:子类覆盖父类的方法,方法名,参数个数,类型,方法的返回类型都一样
重载:类中有两个或者两个以上的方法具有相同的名称,但参数个数或者类型不一样


插播下:指针常量 和 常量指针
反正以前一直靠记忆,都很容易记混,现在找到一个比较好的理解方法了
const--常量  *--指针
谁在前先读谁,谁在前就是谁不可以变
const int * a /int const * a  常量指针,指针指向的内容不能变,指针可以变 
int * const a 指针常量,指针不能变,指针指向的内容可以变,但不能通过指针来修改内容,如 *a = ... 这样子编译虽然能够过,但会发生内存问题,因此也是非法的


3.C++中没有获取数组(字符数组除外)长度的API,字符数组可以通过strlen()来获取长度,字符串可以通过length()获取长度,如:
    int [] n1={1,2,3};char n2[]={'a','b','c'};string n3="def";
    int len1=sizeof(n1)/sizeof(n1[0]);//获取int数组长度
    int len2=strlen(n2);//获取字符数组的长度
    int len3=n3.length();//获取字符串的长度
C++中若数组作为函数参数,如:
int main()                                      
{
intn[]={1,2,3,1,5,6,7,8,0};
test(n);
}
voidtest(intm[])
{
intlen1=sizeof(m)/sizeof(m[0]);
for(inti=0;i<len1;i++)
{
cout<<m[i]<<endl;
}
}
则输出结果为1,即数组n的首元素,因为传递给m的是n的首地址,因此此时m只指向第一个元素,因此长度为1,所以要想使m完全等于n,一定要指明其作用域的范围,这点很容易忽视,因此如果不能很好的把握,最好还是不要选择数组作为函数参数,Java中这点上使用就很方便
int main()                                      
{
intn[]={1,2,3,1,5,6,7,8,0};
test(n,sizeof(n)/sizeof(n[0]));
}
voidtest(intm[],int len)
{
intlen1=len;
for(inti=0;i<len1;i++)
{
cout<<m[i]<<endl;
}
}
输出结果为:1,2,3,1,5,6,7,8,0


4.以32为机器为例,各数据类型所占的字节数

64位的话long为8
当在求一个指针变量时要注意,指针是指地址,所以指针变量所占的字节数就为地址所占的字节数,如32位机器,则地址就为32位
此外,在使用sizeof()求所占字节数时要注意以下几点
4.1

sizeof()内的运算不执行,如:int i=1; sizeof(i++) cout<<i<<endl; 则i的结果仍为1
4.2 sizeof()的结果为无符号整数类型 unsigned int
4.3 sizeof(字符串)要将字符串末尾的'\0'算上,如sizeof("abc")的结果为4 汉字占两个字节,英文字母占一个字节
4.4 sizeof(结构体)时采用摆放元素法,注意两条基本原则:
(一):整体空间为结构体中sizeof最大的成员空间的整数倍,通常在摆放完所有的元素之后考虑这一点;
(二):摆放某元素时当前已占用的内存空间应为该元素类型大小的整数倍
PS:若结构体中又有结构体,则整体空间为父结构体及子结构体中sizeof最大的成员空间的整数倍,同时摆放子结构体时当前已占用的内存空间应为子结构体中最大元素大小的整数倍;若结构体中有数组,则数组不应被当做整体来对待
union联合体所占空间大小为sizeof最大的成员所占的空间,且也要遵循struct的第一条原则;enum枚举体的sizeof为4;空结构体的sizeof为1
4.5 void foo() {} sizeof(foo):错误,函数名称不能进行sizeof操作 sizeof(foo()):错误,因为foo函数返回类型为void 若为int foo() {},则sizeof(foo())的结果为4
4.6 重定义即typedef不占字节,即sizeof操作的结果为0
4.7 关于计算类的sizeof和计算struct的sizeof类似,注意类中有虚函数的话,就会有个虚函数表指针(+4),虚继承基类则会有个虚继承表指针(+4),详情可以查看如下博客:
http://blog.csdn.net/valerie_7/article/details/6757664
1.不存在虚继承:
1.1 没有父类 and 没有成员 and 没有虚函数 :sizeof(类名) = 1
1.2 没有父类 and 有若干个成员 and 没有虚函数 :sizeof(类名) = sizeof(成员)
1.3 没有父类 and 没有成员 and 有虚函数 :sizeof(类名) = 4(32位)/8(64位)
1.4 没有父类 and 有若干个成员 and 有虚函数 :sizeof(类名) = sizeof(成员) +4(32位)/8(64位)
1.5 有一个父类 and 没有成员 and 父子都没有虚函数 :sizeof(类名) = 1
1.6 有一个父类 and 没有成员 and 父子至少一个有虚函数 :sizeof(类名) =4(32位)/8(64位)
1.7 有多个父类 :sizeof(类名) = 注意:单独考虑每个父类,如果该类中父或子至少有一个有虚函数,就都应该有张虚函数表,其他的计算与上面的类似了
总结而言:sizeof(类名) = sizeof(父类成员+子类成员) + 虚函数表指针 最后的结果要是指针和父类成员或者子类成员中最大sizeof的整数倍
2.存在虚继承:
就要考虑子类指向父类的一个指针 sizeof(类名) = sizeof(父类成员+子类成员+虚函数表指针+子类指向父类的一个指针)


未完待续。。。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章