C++入门基础笔记

1、C++第一个程序

程序中\nendl相同,endl表示结束流,在流中起做用!

    #include <iostream>
    using namespace std;
    int main()
    {
        cout << "Hello, world!" << endl;
        return 0;
    }

2、注释

可以通过#if 0#endif来注释语句通过更改0与1来确定是否使用语句块

3、数据类型

  1. 修饰符: signed有符号 unsigned无符号 short短的 long长的
  2. 类型:bool布尔型 char字符型 int整型 float浮点型 double双浮点 voidwchar_t宽字符型
  3. 值范围: float单精度其地址为1位符号,8位指数,23位小数。
    double双精度是1位符号,11位指数,52位小数。char八位字节

typedef 声明

extern声明变量应放在main()前面,
extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。另外,extern也可用来进行链接指定。

extern int c;

enumeration 枚举型

enum color { red, green, blue } c;
c = blue;

默认情况下red的值为0,green为1,以此类推但当:

enum color { red, green=5, blue };

这个情况下时red的值为0,green为5,blue为6.


4、全局变量

全局变量放在mian()前面,所以程序都可以访问,在程序中,局部变量和全局变量的名称可以相同,但是在函数内,局部变量的值会覆盖全局变量的值。局部变量被定义时,系统不会对其初始化,您必须自行对其初始化.全局会自动初始化
int0 char"\0" float0 double0 pointerNULL

常量

  • 整数常量可以带一个后缀,后缀是 U 和 L 的组合,U 表示无符号整数(unsigned),L 表示长整数(long)。

  • 浮点常量当使用指数形式表示时, 必须包含小数点、指数,或同时包含两者。带符号的指数是用 e 或 E 引入的。通过使用后缀 f 或 l常量可以分别指定为 float 或 long double

18.46e0      // 18.46
18.46e1      // 184.6
  • 字符常量
`\` 转义符 
`\a`	 警报铃声 
`\b`	退格键
`\f`	换页符
`\n`	换行符
`\r`	回车
`\t`	水平制表符
`\v`	垂直制表符
`\ooo`	一到三位的八进制数
`\xhh...`	一个或多个数字的十六进制数

定义常量

#define 预处理器

\#define LENGTH 10

const前缀声明指定类型的常量

常量不能更新

const int  LENGTH = 10;

修饰符类型

explicit构造函数用于防止隐式调用!

存储类

  • register 存储类 用于定义存储在寄存器中而不是 RAM 中的局部变量。不能对它应用&
  • static 存储类 指示编译器在程序的生命周期内保持局部变量的存在.
    即在函数中 static int i = 5;局部静态变量 重复调用函数时还能再访问i
  • extern 存储类 在子文件中声明已存在一个已定义的变量或函数的引用
  • mutable 存储类 后面讲解
  • thread_local 存储类 声明的变量仅可在它在其上创建的线程上访问.变量在创建线程时创建,并在销毁线程时销毁。 每个线程都有其自己的变量副本。可以与 static 或 extern 合并。仅应用于数据声明和定义,不能用于函数声明或定义。
thread_local int x;
class X
{
    static thread_local std::string s; 
};
static thread_local std::string X::s; 
void foo()
{
    thread_local std::vector<int> v; 
}

运算符

  • 算术运算符

% 取余运算

  • 关系运算符
  • 逻辑运算符

&& 与(并且) 逻辑与 AND
||(或) 逻辑或 OR
!(非)

  • 位运算符

A = 0011 1100 B = 0000 1101
& 二边为真才为真 ,A&B = 0000 1100 位与 AND
| 有一个为真即真 ,A|B = 0011 1101 位或 OR
^ 二边不一样的真 ,A^B = 0011 0001 位异或 XOR
~ 取反相, ~A = 1100 0011

  • 赋值运算符
C += A//相当于 C = C + A
C -= A//相当于 C = C - A
C *= A//相当于 C = C * A
C /= A//相当于 C = C / A
C %= A//相当于 C = C % A
C <<= 2//等同于 C = C << 2
C >>= 2//等同于 C = C >> 2
C &= 2//等同于 C = C & 2
C ^= 2//等同于 C = C ^ 2
C |= 2//等同于 C = C | 2
  • 杂项运算符

sizeof 返回变量的大小,字节数如sizeof(int),返回4

x = (y < 10) ? 30 : 40; 当Y=10时,X取40 相当于if语句

.点运算符与->箭头运算符 箭头操作符是结构体 或者 对象 指针用来访问其对象 或者 对象成员时用的符号比如struct aaa{int a,int b;};class bb{int a;int b';void test()};当我们定义一个结构体变量的时候比如 aaa t; bb t;往往是通过.符号来获得或者访问其中的成员变量 或者函数如 t.a t.b t.test()但是 如果我们定义的是一个结构体指针aaa *t;bb *t那么就需要用箭头符号来访问了t->a t->b t->test()这么讲你明白了吗

强制转换运算符 把一种数据类型转换为另一种数据类型。
int(2.2000) 将返回 2。

指针运算符 & 返回变量的地址。例如 &a; 将给出变量的实际地址。

指针运算符 * 指向一个变量。例如,*var; 将指向变量 var。


循环

循环类型

  • while(表达式){};
  • for(初始化,表达式,i++){};
  • do{...}while(表达式);

循环控制

  • break跳出(中断)循环体
  • continue跳出本次循环(不中断)
  • goto转移到被标记,(不建议使用)

函数

函数参数

  • 传值调用--oid swap(int x, int y)调用时 swap(a, b);
  • 指针调用--void swap(int *x, int *y)调用时swap(&a, &b);
  • 引用调用--swap(int &x, int &y)调用时swap(a, b);

数字

数学运算

  1. double cos(double);该函数返回弧度角(double 型)的余弦。
  2. double sin(double);该函数返回弧度角(double 型)的正弦。
  3. double tan(double);该函数返回弧度角(double 型)的正切。
  4. double log(double);该函数返回参数的自然对数。
  5. double pow(double, double);假设第一个参数为 x,第二个参数为 y,则该函数返回 x 的 y 次方。
  6. double hypot(double, double);该函数返回两个参数的平方总和的平方根,也就是说,参数为一个直角三角形的两个直角边,函数会返回斜边的长度。
  7. double sqrt(double);该函数返回参数的平方根。
  8. int abs(int);该函数返回整数的绝对值。
  9. double fabs(double);该函数返回任意一个十进制数的绝对值。
  10. double floor(double);该函数返回一个小于或等于传入参数的最大整数。

数组

double balance[] = {1000.0, 2.0, 3.4, 7.0, 50.0};
double salary = balance[9];
int a[3][4] = {{0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11}};//多维数组

指向数组的指针

double *p;
double balance[10];
p = balance;

使用数组名作为常量指针是合法的,反之亦然。因此,*(balance + 4) 是一种访问 balance[4] 数据的合法方式。一旦您把第一个元素的地址存储在 p 中,您就可以使用 *p*(p+1)*(p+2) 等来访问数组元素。

传递数组给函数

从函数返回数组

C++ 不允许返回一个完整的数组作为函数的参数。但是,您可以通过指定不带索引的数组名来返回一个指向数组的指针。如果您想要从函数返回一个一维数组,您必须声明一个返回指针的函数,如下:

\#include <iostream>
\#include <cstdlib>
\#include <ctime> 
using namespace std; 
// 要生成和返回随机数的函数
int * getRandom( )
{
  static int  r[10]; 
  // 设置种子
  srand( (unsigned)time( NULL ) );
  for (int i = 0; i < 10; ++i)
  {
    r[i] = rand();
    cout << r[i] << endl;
  } 
  return r;
} 
// 要调用上面定义函数的主函数
int main ()
{
   // 一个指向整数的指针
   int *p; 
   p = getRandom();
   for ( int i = 0; i < 10; i++ )
   {
       cout << "*(p + " << i << ") : ";
       cout << *(p + i) << endl;
   } 
   return 0;
}

字符串

字符

char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};//字符组
cout << greeting << endl; //输出
  1. strcpy(s1, s2);复制字符串 s2 到字符串 s1。
  2. strcat(s1, s2);连接字符串 s2 到字符串 s1 的末尾。
  3. strlen(s1);返回字符串 s1 的长度。
  4. strcmp(s1, s2);如果 s1 和 s2 是相同的,则返回 0;如果 s1<s2 则返回值小于 0;如果 s1>s2 则返回值大于 0。
  5. strchr(s1, ch);返回一个指针,指向字符串 s1 中字符 ch 的第一次出现的位置。
  6. strstr(s1, s2);返回一个指针,指向字符串 s1 中字符串 s2 的第一次出现的位置。

String类

string str1 = "Hello";
str1.size();//返回长度

指针

指针可以理解为是一个变量,但这变量只存储地址信息,地址

int var = 20;// 实际变量的声明
int *ip;// 指针变量的声明
ip = &var;// 在指针变量中存储 var 的地址

空指针

int *ptr = NULL;空指针,其地址值为0,空指针中不允许访问地址为 0 的内存,
所以cout <<"ptr的值" <<*ptr;会报错,应先if(ptr)判断

指针数组

\#include <iostream>
using namespace std;
const int MAX = 3;
int main ()
{
   int  var[MAX] = {10, 100, 200};
   int *ptr[MAX];  //指针数组
   for (int i = 0; i < MAX; i++)
   {
      ptr[i] = &var[i]; // 赋值为整数的地址
   }
   for (int i = 0; i < MAX; i++)
   {
      cout << "Value of var[" << i << "] = ";
      cout << *ptr[i] << endl;
   }
   return 0;
}

指向指针的指针(多级间接寻址)

   int  var;
   int  *ptr;
   int  **pptr;
   var = 3000;   
   ptr = &var;// 获取 var 的地址   
   pptr = &ptr;// 使用运算符 & 获取 ptr 的地址

传递指针给函数

 getSeconds( &sec );//调用时
void getSeconds(unsigned long *par)
{
   // 获取当前的秒数
   *par = time( NULL );
   return;
}
getAverage( balance, 5 );
double getAverage(int *arr, int size)
{
//...
}

从函数返回指针

C++ 不支持在函数外返回局部变量的地址,除非定义局部变量为 static 变量。

int * myFunction()
{
}
//调用
int *p; 
p = getRandom();

引用

其与直接使用参数的区别在于,不用开辟一块内存,进行赋值拷贝动作。(可以理解这是一个另名)

把引用作为参数

void swap(int& x, int& y);
int main ()
{
   int a = 100;
   int b = 200;   
   swap(a, b);// 调用函数来交换值
   return 0;
}
void swap(int& x, int& y)
{
   int temp;
   temp = x; /* 保存地址 x 的值 */
   x = y;    /* 把 y 赋值给 x */
   y = temp; /* 把 x 赋值给 y  */  
   return;
}

把引用作为返回值

double vals[] = {10.1, 12.6, 33.1, 24.1, 50.0};
double& setValues( int i )
{
  return vals[i];   // 返回第 i 个元素的引用
}
int main ()
{
setValues(1) = 20.23; // 改变第 2 个元素
setValues(3) = 70.8;  // 改变第 4 个元素
}

注意:1.不能返回局部变量的引用。2.不能返回函数内部new分配的内存的引用 3.可以返回类成员的引用,但最好是const。


日期与时间

程序中引用 <ctime> 头文件。

struct tm {  //结构体
  int tm_sec;   // 秒,正常范围从 0 到 59,但允许至 61
  int tm_min;   // 分,范围从 0 到 59
  int tm_hour;  // 小时,范围从 0 到 23
  int tm_mday;  // 一月中的第几天,范围从 1 到 31
  int tm_mon;   // 月,范围从 0 到 11
  int tm_year;  // 自 1900 年起的年数
  int tm_wday;  // 一周中的第几天,范围从 0 到 6,从星期日算起
  int tm_yday;  // 一年中的第几天,范围从 0 到 365,从 1 月 1 日算起
  int tm_isdst; // 夏令时
}

示例

\#include <stdio.h>
\#include <time.h>
int main ()
{
   clock_t start_t, end_t;
   double total_t;
   start_t = clock();//clock_t clock(void)返回程序执行起(一般为程序的开头)处理器时钟所使用的时间
   time_t rawtime;
   struct tm *info; //结构体tm
   char buffer[80];
   time( &rawtime );//返回系统的当前自 1970 年 1 月 1 日以来经过的秒数
   info = localtime( &rawtime );//使用 timer 的值来填充 tm 结构
   printf("当前的本地时间和日期:%s", asctime(info));
   end_t = clock();
   total_t = (double)(end_t - start_t) / CLOCKS_PER_SEC;//CLOCKS_PER_SEC是标准c的time.h头函数中宏定义的一个常数,表示一秒钟内CPU运行的时钟周期数,用于将clock()函数的结果转化为以秒为单位的量
   printf("CPU 占用的总时间:%f\n", total_t  );
   return(0);
}

基本输入输出

  • cout 输出 cout <<"test"<<endl;
  • cin 输入 cin >> name;
  • cerr 错误流 cerr << "test" << endl;
  • clog 日志流 clog << "test" << endl;

数据结构

strcpy(str1,str2);把str2的字符串数据复制到str1中!

指向结构的指针

printBook( &Book1 );//main调用
void printBook( struct Books *book )
{
   cout << "书标题  : " << book->title <<endl;
   cout << "书作者 : " << book->author <<endl;
   cout << "书类目 : " << book->subject <<endl;
   cout << "书 ID : " << book->book_id <<endl;
}

类&对象

类定义

\#include <iostream>
using namespace std;
class Box
{
   public:
      double length;   // 盒子的长度
      double breadth;  // 盒子的宽度
      double height;   // 盒子的高度
      double getVolume(void);// 返回体积
};
double Box::getVolume(void)  //范围解析运算符::定义该函数
{
    return length * breadth * height;
}
int main()
{
Box Box1;
double volume = 0.0;// 用于存储体积 
Box1.length=6; 
Box1.breadth=7;
Box1.height=5;
volume = Box1.getVolume();
  cout << "Box1 的体积:" << volume <<endl;
return 0;
}
}

继承

格式

class Rectangle: public Shape{}Shape为基类

多继承

class <派生类名>:<继承方式1><基类名1>,<继承方式2><基类名2>,…{<派生类类体>};

虚继承

格式:class 类名: virtual 继承方式 父类名

  • 举例来说:假如类A和类B是由类X继承而来(非虚继承且假设类X包含一些成员),且类C同时继承了类A和B,那么C就会拥有两套和X相关的成员(可分别独立访问,一般要用适当的消歧义修饰符)。但是如果类A虚继承自类X,那么C将会只包含一组类X的成员数据。

重载运算符和重载函数

重载函数

class printData 
{
   public:
      void print(int i) {
        cout << "整数为: " << i << endl;
      } 
      void print(double  f) {
        cout << "浮点数为: " << f << endl;
      }
};

运算符重载

      // 重载 + 运算符,用于把两个 Box 对象相加
      Box operator+(const Box& b)
      {
         Box box;
         box.length = this->length + b.length;
         return box; //返回box
      }
     // 重载小于运算符( < )
      bool operator <(const Distance& d)
      {
         if(feet < d.feet)
         {
            return true;
         }
         if(feet == d.feet && inches < d.inches)
         {
            return true;
         }
         return false;
      }
      //重载输出      
     friend ostream &operator<<( ostream &output, 
                                       const Distance &D )
      { 
         output << "F : " << D.feet << " I : " << D.inches;
         return output;            
      }
      //重载输入 
      friend istream &operator>>( istream  &input, Distance &D )
      { 
         input >> D.feet >> D.inches;
         return input;            
      }

其它重载请查看 菜鸟教程

posted @ 2018-06-09 13:43  天祈笨笨  阅读(209)  评论(0编辑  收藏  举报