记录2--

来源:互联网 发布:ubuntu游客创建用户 编辑:程序博客网 时间:2024/05/21 11:04
//***********************************************************char *c[] = { "ENTER", "NEW", "POINT", "FIRST" }; char **cp[] = { c+3, c+2, c+1, c }; char ***cpp = cp; c是一个指针数组,每个数组单元都是一个指针,指向一个字符串.  c[0]="ENTER"......c[3]="FIRST" 由于[]与*运算本质几乎是一致的,以下用[]替换*更容易理解。 c[i]=*(c+i) c和c+i都是char*[]类型,它可以退化成char**类型,它正好是一个char**数组   cp[0]=c+3 .....cp[3]=c 引用后cp[0][0]=*(c+3)=c[3]="FIRST" cp是char**[]类型,它可以退化成char***类型,正好与cpp类型一致。 


//*******************************int const c=21;  //变量c的值不能改变const int *d=&a;  //指针变量d指向的值不能改变int *const e=&b;  //指针的指向不能改变int const *f const =&a; //指针不能改变,指针指向的值也不能改变。const 读取方法如:  int  const *  const p;找到第一个const,  后面除了有个const之外 就是 *  和 p,那么见证奇迹的时刻来了,const  *  p  这就是我们要的结果,p指向的内容不可变找到第二个const,  后面只有个p,   那么见证奇迹的时候到了const  p,,这就是结果, p不可变++规则总结如下:找到const, 再看后面除了const的内容,是什么东西,那个东西不能变即是
//***多维数组*****已知int a[3][4];则下列能表示a[1][2]元素值的是*(*(a+1)+2)在多维数组中,数组名是第一个数组的地址. 注意:这里a不是第一个元素的地址,而是第一个维数组的地址,a[0][0]才是表示的一维数组第一个元素的地址. 地址 + 1表示向下移一层. 到第二个数组地址*(a+1)表示第二行的首地址,和a[1]一样。 *(a+1)+2第二行第三个数字的地址 *(*(a+1)+2)就是第二行第三个数字的值 
//*******类的概念***在C++面向对象编程语言中,以下阐述不正确的是:a接口中可以用虚方法b.一个类可以实现多个接口c.接口不能被实例化d.接口中可以包含已经实现的方法首先所谓的接口是指只包含纯虚函数的抽象类,和普通的抽象类不一样。所以A不对,必须是纯虚函数。然后B是正确的没有问题。刚才说接口是特殊的抽象类,抽象类的唯一作用就是创建派生类,不能定义抽象类的对象,所以C是正确的。对于D,接口即只包含纯虚函数的抽象类,所以D是不对的

//*********************char a=101;int sum=200;a+=27;sum+=a; printf("%d\n",sum);char为有符号类型,占1个字节,也就是8位,其中最高位位符号位,取值范围为-128~127; a=101+27=128>127; 表示为1000 0000,计算机中以补码形式存储, 即为-128; sum=200+(-128)=72; 

//*****C++中的结构体和类的比较***在C语言中结构体是不能继承的,但是在C++中也有结构体的概念。区别:结构体继承的默认访问权限为public,类继承的默认访问权限为private。C++中结构体的成员变量访问权限也有三种:pubic、protected、private,默认访问权限是public;但类的默认访问权限是private。相同:可以有数据成员,方法,构造函数等。


void GetMemory(char *p){    p = (char *)malloc(100);}void Test(void){    char *str = NULL;    GetMemory(str);    strcpy(str, "hello world");    printf(str);}GetMemory(char *p);这里*p是形参,是局部变量不能将malloc申请的地址指针返回,造成内存泄露 更严重的是执行GetMemory(str);后str依然为NULL 。执行strcpy(str, 'hello world');就会出错 传指针是可以通过指针的指向来改变变量的值,但是由于传入的是指针本身的副本,指针本身的值并不改变。

C++将父类的析构函数定义为虚函数,作用有:释放子类指针时能正确释放父类对象。C++中假设有基类为fa,它的派生类为son,*fa = new son();如果有基类的析构函数不是虚函数。在delete fa或者释放*fa的时候将只会调用基类的析构函数;如果基类的析构函数为虚函数,在delete fa或者释放*fa的时候会先调用派生类(这里也就是son)的析构函数,再调用基类的析构函数。


void main(){int a[5] = { 1,2,3,4,5 };int *p = (int *)(&a + 1);printf("%d", *(p - 1));system("pause");}数组名a可以作为数组的首地址,而&a是数组的指针。int *p=(int *)(&a+1);//这条语句中&a代表整个数组的地址,+1应加上sizeof(a)的长度,故指针p指向a[5]处。printf("%d",(*p-1));//(*p-1) == a[4],语句输出a[4]的值,为5

struct Node{   int size;   char data[0];};char data[0];百度  柔性数组,它只能放在结构体末尾,是申明一个长度为0的数组,就可以使得这个结构体是可变长的。柔性数组(Flexible Array)也叫伸缩性数组,也就是变长数组,反映了C语言对精炼代码的极致追求。 这种代码结构产生于对动态结构体的需求, 比如我们需要在结构体中存放一个动态长度的字符串时,就可以用柔性数组。 C99使用不完整类型来实现柔性数组,标准形式如下: struct MyStruct  {  int a;  double b;  char c[]; // or char c[0]; 也可以用其他数据类型;  };数组c 不占用MyStruct的空间,只是作为一个符号地址存在,而且必须是结构体的最后一个成员。


(1) 什么是类模板一个类模板(也称为类属类或类生成类)允许用户为类定义一种模式,使得类中的某些数据成员、默写成员函数的参数、某些成员函数的返回值,能够取任意类型(包括系统预定义的和用户自定义的)。如果一个类中数据成员的数据类型不能确定,或者是某个成员函数的参数或返回值的类型不能确定,就必须将此类声明为模板,它的存在不是代表一个具体的、实际的类,而是代表着一类类。(2)类模板定义定义一个类模板,一般有两方面的内容:A.首先要定义类,其格式为:template <class T>class foo{……}foo 为类名,在类定义体中,如采用通用数据类型的成员,函数参数的前面需加上T,其中通用类型T可以作为普通成员变量的类型,还可以作为const和static成员变量以及成员函数的参数和返回类型之用。例如:template<class T>class Test{private:    T n;    const T i;    static T cnt;public:    Test():i(0){}    Test(T k);    ~Test(){}    void print();    T operator+(T x);};B. 在类定义体外定义成员函数时,若此成员函数中有模板参数存在,则除了需要和一般类的体外定义成员函数一样的定义外,还需在函数体外进行模板声明例如template<class T>void Test<T>::print(){    std::cout<<"n="<<n<<std::endl;    std::cout<<"i="<<i<<std::endl;    std::cout<<"cnt="<<cnt<<std::endl; }如果函数是以通用类型为返回类型,则要在函数名前的类名后缀上“<T>”。例如:template<class T>Test<T>::Test(T k):i(k){n=k;cnt++;}template<class T>T Test<T>::operator+(T x){               return n + x;               }C. 在类定义体外初始化const成员和static成员变量的做法和普通类体外初始化const成员和static成员变量的做法基本上是一样的,唯一的区别是需再对模板进行声明,例如template<class T>int Test<T>::cnt=0;template<class T>Test<T>::Test(T k):i(k){n=k;cnt++;}(3)类模板的使用 类模板的使用实际上是将类模板实例化成一个具体的类,它的格式为:类名<实际的类型>。模板类是类模板实例化后的一个产物。例子:template<class T>class Foo {T tVar;public:Foo(T t) : tVar(t) { }};class FooDerived : public Foo<int> {public:FooDerived() :Foo<int>(12) {}};//Foo<int>   或  Foo<double>  就是两个Foo的模板类。 可以直接生成对象 Foo<int> fi;   Foo<double>  fd;  都正确


//************声明一个数组指针,随便来一个数组指针是  int(*p)[10]声明一个函数指针,随便来一个函数指针  int (*pf)(int *) 题目:声明一个指向含有10个元素的数组的指针,其中每个元素是一个函数指针,该函数的返回值是int,参数是int*,正确的是()int (*(*p)[10])(int *)解析:   先看未定义标识符p,p的左边是*,*p表示一个指针,跳出括号,由于[]的结合性大于*,所以*p指向一个大小为10的数组,即(*p)[10]。左边又有一个*号,修释数组的元素,*(*p)[10]表示*p指向一个大小为10的数组,且每个数组的元素为一个指针。跳出括号,根据右边(int *)可以判断(*(*p)[10])是一个函数指针,该函数的参数是int*,返回值是int。