C++第一课

一、C++简介

        c++是一门以c为基础,发展而来的面向对象的程序设计语言。

组成:语言本身(基础语法)+  库(标准库STL)

二、第一个C++程序

#include <iostream>
#include <stdio.h> //C++全面兼容C语法

int main()
{
    printf("hello world!\n");
    std::cout << "hello C++" << std::endl;

    int a,b;
    std::cin >> a >> b;
    std::cout << a << "+" << b << "=" << a+b << std::endl;

    return 0;
}

iostream:被包含的头文件名称。

  cin :    表示标准输入    即stdin
cout :(console output)   表示标准输出    即stdout
cerr :   (console input)      表示标准错误    即stderr

<< :      1.左移运算符;

            2.  输出运算符(放到cout的右边,用于输出,把数据输出到标准输出)

             在C++中,一切都是对象(拥有行为和属性),可以设置输出对象(cout)的属性
                如:
                    设置输出的整数的进制
                    std::cout << std::hex;   //设置输出对象的属性,每次输出数据都是16进制

>>:        1.右移运算符;

             2.输入运算符(放到cin的右边,用于输入,用于从标准输入获取数据,存入到指定的变量)

                 cin >> 变量;
                    cin:console input  控制台输入,本身是一个全局变量

::

                作用域运算符(std是“standard”,是标准c++库中的一个作用域,其中定义了标准库中的所有名字,其中专门用来存放名字的作用域称为名字空间namespace)。例如,std::cout指的是cout来自于std这个名字空间。

后缀名        .cpp

三、名字空间(namespace)

1.功能

        用于存放各种名称,达到避免名字冲突。

2.本质

        一块由程序员命名的内存区域。

3.定义方式

        namespace 是定义名字空间的关键字

4.使用方法(先定义再使用)

        1.使用作用域运算符(名字空间名称::要访问的名字)例如,std::cout 

        2.名字空间指令(using指令)例如,using namespace std; //把指定的名字空间中的   所有名字  导入到当前作用域,std::cout  ------->  cout 
        3.名字空间声明(using 声明)using 名字空间名称::名字;例如, using std::cout;//把指定的名字空间中的  指定名字   导入到当前作用域

例如:

#include <iostream>

using namespace std;
int a = 100;
namespace ns1
{
    int a = 101;
    namespace ns2
    {
        int a = 102;
    };
};

void fun()
{
    a = 1024;
}

int main()
{
    int a = 103;
    std::cout << "a=" << a << std::endl;
    std::cout << "a=" << ns1::ns2::a << std::endl;
    std::cout << "a=" << ::a << std::endl;

    cout << "hello" <<endl;

    return 0;
}

四、C++中的函数

1.默认参数(default argument)

须遵循的规则:

        1.靠右原则

                定义时:如果某一个参数设置了默认值,那么它右边所有的参数都必须有默认值

                使用时:某一个参数使用了默认值,那么它后面的所有参数都必须使用默认值(不能跳着传参)
        2.互斥原则

                 在函数的声明和定义分开的时候,只能把默认参数设置到声明的地方,定义的地方不能有默认参数

例如,设计一个函数,可以输出一个一维数组,数组元素默认以空格隔开,也可以指定的特殊的分隔符号

#include <iostream>

using namespace std;

void print_arr(int *arr,int numsSize,char ch = ' ')
{
    for(int i = 0;i<numsSize;i++)
    {
        cout << a[i] << ch;
    }
    cout << "\b" << ' ';
    cout << "\n";
}

int main()
{
    int a[5] = {1,2,3,4,5};
    print_arr(a,5,'#);

    return 0;
}

2.函数重载(overload)

        在C++中允许函数名重复使用,即使用同一个函数名可以定义多个不同的函数,实现相似的功能
例如

#include <iostream>

using namespace std;

int sum(int a,int b)
{
    count << "sum_int _int" << endl;
    return a+b;
}

double sum(double a,double b)
{
    cout << "sum_double_double" << endl;
    return a+b;
}

double sum(double a,int b)
{
    cout << "sum_double_int" <<endl;
    return a+b;
}


int main()
{
    cout << sum(1,2) << endl;
    cout << sum(1.1,2.2) << endl;    
    cout << sum(1.1,2) << endl;    

    return 0;
}
    

函数满足重载关系的基本条件

        1.在相同的作用域下面;

        2. 函数名相同(不受返回值类型影响)

        3.参数的类型列表不相同(个数,类型,是否有const属性)

存在的问题

    例如:  int sum(int a=0,int b=0,int c=0);
                 int sum(int a,int b);
                    sum();   //YES 
                    sum(1,2,3);  //YES 
                    sum(1);     //YES
                    sum(1,2);   //二义性错误,不知道以sum(1,2);调用第二个,还是以sum(1,2,0);调用第一个

编译器换名机制

        将函数名和参数类型结合在一起形成一个新的名字,替换掉原来的名字。

        验证:  g++ -c  sum.cpp -o  sum.o       编译为二进制文件(预处理/编译/汇编)
                    sum.o里面就有sum.cpp编译之后的所有符号信息
                    通过nm命令可以查看二进制文件的符号表信息
                        如:   nm   sum.o  
                                0000000000000014 T  _Z3sumdd
                                000000000000002e T  _Z3sumdi
                                0000000000000000 T  _Z3sumii

            _Z3sumii     _Z3sumdi       _Z3sumdd  就是替换之后的函数名
 

 3.混合编程(extern "C")

         C++代码中调用了使用gcc编译的函数 。

//main.c
#include <stdio.h>
#include "nb.h"

int main()
{
    int a[5] = {1,2,3,4,5};
    printf_arr(a,5);

    return 0;
}

   

//2main.cpp

#include <iostream>
#include "nb.h"

using namespace std;

int main()
{
    cout << "in Cpp" << endl;
    int a[5] = {1,2,3,4,5};
    printf_arr(a,5);

    return 0;
}

 

//./bin/nb.c

#include "nb.h"
#include <stdio.h>

void printf_arr(int *arr,int numsSize)
{
    for(int i = 0;i<numsSize;i++)
    {
        printf("%d ",arr[i]);
    }
    printf("\n");
}

 

//./bin/nb.h

#ifndef _NB_H_
#define _NB_H_

#ifdef _cplusplus
extern "C"
{
#endif
void printf_arr(int *arr,int numsSize);

#ifdef _cplusplus
}
#endif
#endif

 

nb.h/nb.c ------>编译成动态库
                gcc -shared -fpic -o libnb.so  nb.c

main.c   ----->调用这个函数 
                gcc main.c -I./lib/  -lnb  -L./lib
                export LD_LIBRARY_PATH=./lib

 2main.cpp  ----->调用这个函数 
                g++ 2main.cpp -I./lib/  -lnb  -L./lib
                /tmp/ccI9ZyOR.o:在函数‘main’中:
                2main.cpp:(.text+0x6a):对‘print_arr(int*, int)’未定义的引用
                collect2: error: ld returned 1 exit status
解决方法:
                在声明这个函数的时候,告诉编译器,这个函数的调用方法按照C语言的方式进行(不对函数名进行特殊处理)

4.内联函数(inline)

        使用inline关键字修饰的函数,称为内联函数。
格式:
        inline 返回值类型  函数名(形式参数类型列表)
        {
            函数体;
        }
特点

        编译器在编译的时候,会将函数的函数体"复制"到函数的调用点
        在调用函数的时候,就不需要跳转到函数定义的地方执行,可以节省函数调用的开销,提高程序运行效率

        一般来说,内联函数都是简短.逻辑简单,不能包含复杂的运算(如:循环,递归)

        一般使用内联函数来替换宏函数(宏定义)

    

 //定义一个宏,返回两个数中小的那一个
     #define MIN(a,b) ((a)<(b)?(a):(b))    //有bug
     int a = 7,b = 8;
     MIN(a++,b);  //按照原来的意思,a只需要自增一次

 //宏展开之后:
      ((a++)<(b)?(a++):(b))   //导致a多自增一次

 //正确:
        inline int MIN(int a,int b)
        {
            return a<b?a:b;
        }

  五、C++中的结构体/共用体/枚举

   1.共用体(union)

        C和C++中的共用体没有区别!!!
        共用体和结构体有什么区别?            

        1、存储方式

                结构体:结构体中的每个成员都有自己独立的存储空间,成员的存储顺序按照声明的顺序依次排列。

                共用体:共用体的所有成员共享同一块存储空间,同一时刻只能存储其中一个成员的值。 

        2、内存占用

                结构体:内存占用为其所有成员占用内存之和。

                共用体:内存占用为其最大成员所占用的内存大小。

        3、访问方式

                结构体:可以同时访问结构体的所有成员。

                共用体:在同一时刻只能访问其中一个成员。

2.枚举(enum)

        枚举就是把一个变量所有可能出现的值,列举处理,变量的值,只能是枚举值中的一种
 

#include <iostream>

using namespace std;

enum class WEEK:char{MON,TUE,WED,THU,FRI,SAT,SUN};
enum class WORKDAY{MON,TUE,WED,THU,FRI};

int main()
{
    WEEK w;
    cout << sizeof(w) <<endl;
    w = WEEK::MON;

    int x = (int)WEEK::MON;
    cout << "x="<< x << endl;

    return 0;
}

3.结构体(struct)

       在面试对象的编程语言中,一切都是对象 , C++中的结构体能够包含函数,用函数来表示这个对象的"行为"

        任何对象都不仅仅只有静态的属性(数据)----成员变量,还有动态的行为(函数) ----成员函数

//舔狗代码
#include <iostream>
#include <string.h>

using namespace std;

struct Dog
{
    int age;
    char name[32];
    void Jiao()
    {
        cout << "wangwangwang!" << endl;
    }
    void Tian()
    {
        cout << "宝,天气越来越热了,没有你的冷暴力真不知道怎么办了"<< endl;
        cout << "my name is " << name << " i am " << age <<"years old!" << endl;
    }
};

int main()
{
    Dog w;
    w.age = 21;
    strcpy(w.name,"lisi");
    w.Jiao();
    w.Tian();

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值