c++复习笔记1

(编程基础)

1. 判断是否为字母,使用 isalpha(str[i]) 函数,原型为int isalpha(int ch) ;

    头文件:#include<cctype>(旧版本的编译器使用<ctype.h>),包含<iostream>库也可使用

    函数为isupper和islower的合并。

2. p[i]是*(p+i)的语法糖,在函数调用中,数组会退化为指针;

    int sum (int a[]) ;

    等价于 int sum (int *a) ;

    等价于 int sum(int a[10]);

3.存储类别

    从空间上划分为全局变量和局部变量;

   从时间上分为动态存储和静态存储方式和动态存储方式。

   变量和函数有两种属性,即数据类型和存储方式。变量的作用域有三种:全局变量(函数外声明的变量)、局部变量(函数内部声明的变量)、文件级变量(static 修饰的全局变量)。

4. 对象生命周期

  变量存储期分为自动存储期和静态存储期。全局变量、文件内static变量、局部static变量(只能被初始化一次),称为静态变量,持有静态存储期。没有指定static的局部变量,持有自动存储期,程序进入它持有的语句块时分配内存,该语句块结束时释放内存,随用随消。

所有函数和变量都具有作用域和生存期,分别对应空间特性和时间特性。static关键字改变了时间特性,局部变量的作用域是不变的,但文件级变量或函数加static声明则将其外部链接性改为内部链接性,作用域改变。

 所有函数都具有文件级作用域和静态生存期,函数定义时使用static关键则将函数声明为内部函数。

5.内存区域寿命

 1)静态变量  :从程序开始到程序结束一直存在(静态变量区);

  2)自动变量 : 声明该变量的语句块结束时随之结束,并释放内存(栈区,函数返回时结束);

  3)malloc()或 new 分配的内存: 动态内存,调用free()或 delete时结(堆区)。

6.存储类型修饰符:auto、static、register、extern

  1)static:对应静态生命周期,如果是定义在函数外,那么该对象具有内部链接,其它程序文件不能对其访问。如果是定义在函数内,那么该对象具有无链接,函数外不能对其访问。

  2)auto:对应自动生命周期。只能修饰局部变量,在栈中存储。

  3)register : 只能修饰局部变量或者形参,将内存中的变量升级到cpu寄存器中存储,加快访问速度。存储cpu的变量,速度快但数量有限,通常用来优化。用于频繁使用的变量。编译器一般做了优化,一般不用。

  4)extern : 外部链接,函数内的extern变量可以全局访问(具有内部链接),全局的extern变量可以在其他文件访问(具有外部链接)。extern变量不能重复定义,一般不初始化。

7.存取限定符: const、volatile

1)const与一般变量 : 将变量设为只读,const修饰的变量必须初始化并且不能再被赋值,const形参必须接收const类型的实参。

2)const与指针

    指向常量的指针(const int * a)不能用于改变过其所指对象的值,也就是不能改变 *a (指针指向的变量)的值。要想存放常量对象的地址,只能使用指向常量的指针

      常量指针(int * const a)必须初始化,初始化后值(存放在指针中的地址)就不能改变。常量指针不变的是指针自己的值,而不是其对象的值。

3)const与类

      不能在const函数中调用非const的成员函数。不能用const修饰static成员函数。const限定符是函数类型的一个组成部分,因此能通过有无const进行函数重载

4)const与引用     

普通引用与const引用(指向const对象的引用)对不可寻址对象的初始化

首先要明白引用的规则:引用是在变量内部存放地址,但是对于不可寻址的量(如常量)或者需要类型转换不能直接进行引用初始化的量(例如int引用需要指向double),编译器首先建立一个临时的量,然后令引用存储该临时量的地址。

倘若对这种引用进行修改,实际修改的是临时的变量,而非在字面上指向的量,这显然是没有意义的。为了防止

这种容易引起误解的修改(误以为修改了字面上指向的量),C++标准只允许const引用指向这种需要建立临时对象进行的引用操作,即规定不可对其进行修改。

      int &temp = 1000; //错误

      const int &temp =  1000; //正确

    

volatile:volatile 关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如:操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。声明时语法:int volatile vInt; 当要求使用 volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据。而且读取的数据立刻被保存。

关于volatile的问题,转自:https://blog.csdn.net/csyounth/article/details/12773289

       1)一个参数既可以是const还可以是volatile吗?解释为什么。
       2); 一个指针可以是volatile 吗?解释为什么。
       3); 下面的函数有什么错误:
       int square(volatile int *ptr)
       {
         return *ptr * *ptr;
       }
      下面是答案:
      1)是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改 它。
      2); 是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。
       3) 这段代码有点变态。这段代码的目的是用来返指针*ptr指向值的平方,但是,由于*ptr指向一个volatile型参数,编译器将产生类似下面的代码:
      int square(volatile int *ptr)
     {
        int a,b;
        a = *ptr;
        b = *ptr;
        return a * b;
      }
      由于*ptr的值可能被意想不到地该变,因此a和b可能是不同的。结果,这段代码可能返不是你所期望的平方值!正确的代码如下:
     long square(volatile int *ptr)
     {
       int a;
       a = *ptr;
       return a * a;
     }

猜你喜欢

转载自blog.csdn.net/qq_38282762/article/details/81198487
今日推荐