C++对于C的扩展

前言:此为本人的一些笔记总结,只针对一部分内容,并非完整的C++对于C的扩展。

语法检查增强

C++是强语法语言,C语言中的一些不会报错的写法,在C++中会编译报错。

声明与定义

如果先后声明了两次变量,一个赋值,一个未赋值,在C语言的编译中会认为赋值的是定义,未赋值的是声明变量,编译时不会出错。但是C++不区分这是声明还是定义,所以编译时认为你重复定义了变量。

C语言

#include <stdio.h>
int a = 10 ; //赋值,当做定义。
int a ;    //未赋值,当做声明。
//若无第2行,只有第3行,就是定义变量a ,只是未被初始化

C++如此做,编译会出错。C++不区分这是声明还是定义,所以编译时认为你重复定义了变量。

#include <iostream>
using namespace std;

int main(int argc, char *argv[])
{
    int a = 10 ;
    int a ;
    cout<<"a = "<< a <<endl;
    return 0;
}

编译结果 

C++赋值,可以在声明时定义,也可以之后再赋值。赋值时直接写变量名,不要加变量类型。

#include <iostream>
using namespace std;

int main(int argc, char *argv[])
{
    int a = 10 ;
    a = 20;
    cout<<"a = "<< a <<endl;
    return 0;
}

函数的参数类型

C语言中函数不指定形参的类型,那么该函数可以接收任何类型的参数。

虽然C语言语法弱,但是我们可以认为避免。

#include <stdio.h>
void func(i)
{
    printf("i=%d\n",i);
}

void funcs(i)
{
    printf("i=%s\n",i);
}

int main(int argc, char *argv[])
{
    func(100);
    funcs("string");
    return 0;
}

运行结果 

在C++中须指定参数的类型,同名的函数若参数类型,程序在调用函数时,会跟据参数类型的不同而调用不同的函数(重构)。

#include <iostream>
using namespace std;
void func(int i)
{
    cout<<"i 是 int :"<< i << endl;
}
void func(string i)
{
    cout<<"i 是 string :"<< i << endl;
}

int main(int argc, char *argv[])
{
    func(101);
    func("love");
    return 0;
}

 运行结果

类型转换更严格

C++中,不同类型的变量一般是不能直接赋值的,需要相应的强制转换。

#include <iostream>
using namespace std;
typedef enum colour{ red , green , blue } color;
int main(int argc, char *argv[])
{
    color mycolor = green ;
    mycolor = 10 ;
    return 0;
}

编译结果

 以上代码,在C语言中可以通过编译。

结构体增强

C语言中定义结构体实例必须加struct,C++中可加可不加。

C++的结构体中可以定义方法函数,C语言中不可以。

C++调用结构体的函数,需要用实例调用。

#include <iostream>
using namespace std;
struct student{
    int num ;
    char name[32];
    //结构体方法
    void func(){
        cout<<"  大家好,我是 "<<num<<" 号的"<<name<<",很高兴认识大家"<<endl;
    }
};

int main(void)
{
    struct student lucy = {100 , "lucy"} ;//C语言定义结构体实例时必须加struct
    student Jack = {101 ,"Jack"}; //C++可加可不加struct
    cout<<"调用成员变量 Jack.num = "<< Jack.num <<endl ;
    cout<<"调用成员方法 "<<endl;
    Jack.func();
    return 0;
}

运行结果

  

增加bool类型

C++的bool类型有两种常量true(转换为整数1)和false(转换为整数0)标志状态。

bool、true、false都是关键字。

bool类型1个字节大小,赋值bool时,非零值会自动转化为true(1),0值会自动转化为false(0)。

#include <iostream>
using namespace std;

int main(void)
{
    cout<<"bool值大小 :"<< sizeof(false)<<endl;
    bool flag = true ;
    cout<<"true = "<< flag <<endl;
    flag = false ;
    cout<<"false ="<< flag <<endl;
    flag = 1001 ;
    cout<<"flag = "<< flag <<endl;
    return 0;
}

 运行结果

三目运算符

C++的三目运算符返回的值为变量本身(引用),可以为左值,可以被赋值。

C语言的三目表达式返回值为数据值,为右值,不能被赋值。

int main(void)
{
    int a = 101 ;
    int b = 20 ;
    cout<<"a = "<<a<<endl;
    cout<<"b = "<<b<<endl;
    cout<<"======= "<<endl;
    a>b?a:b = 1001 ;
    cout<<"a = "<<a<<endl;
    cout<<"b = "<<b<<endl;
    return 0;
}

运行结果

 

左值(Lvalue),L代表location,表示内存可以寻址,可以赋值。

右值(Rvalue),R代表read,表示可以读取的值。

例如:int temp = 1001;temp在内存中有地址,而1001没有,但是可以读到它的值。

const 常量

C语言中const修饰全局变量,变量名只读。默认是外部链接(其他源文件也能访问)。既然是变量,就会分配内存空间。全局定义const,不能通过&地址修改空间内容。局部定义const不能通过变量名修改值,但是可以通过取地址来修改(内容存储在栈区,栈区可读写)。

#include <stdio.h>
const int num = 100 ;
//外部文件定义,使用时要先声明num
extern const int num;
int main(void)
{
    printf("num = %d \n",num);
    const int d = 10 ;
    printf("d = %d \n",d);
    int *p=(int *)&d ;
    *p=200;
    printf("修改d = %d \n",d);
    return 0;
}

运行结果

C++中,const 定义一个不能改变的普通变量,即常量。常量不会被分配内存。

定义基础类型 const int num=10时,编译器会将标识符放到符号表中,不分配内存,当对其取地址时,才会分配内存。

在编译时,程序会从符号表中取值,而不是内存。

在函数外定义的const作用域为当前文件,其他文件不可见。

pi.cpp

const float pi=3.14 ;//main.cpp不可见此变量

main.cpp

#include <iostream>
#include <string>
using namespace std;
const int pi = 100 ;//赋值,当前文件可见
int main(void)
{
    cout<<"pi ="<<pi<<endl;
}

运行结果

 如果要在其他源文件使用const定义的变量,那么就需要在定义时加extern。

fun.cpp

extern const int num = 314 ;

main.cpp

#include <iostream>
#include <string>
using namespace std;
extern const int num;
int main(void)
{
    cout<<"num = "<< num <<endl;
    const int data = 10 ;
    cout<<"data = "<< data <<endl;
    int *p = (int *) &data ;
    *p=200;
    cout<<"*p = " << *p << endl;
    cout<<"data = "<<data<<endl;
}

运行结果

以上程序中,只是修改了内存地址中的内容,由于访问变量名时,是从符号表中取值,符号表中的值并没有改变,所以值没有变化。

当const 用一个变量初始化时,系统会分配内存。修改地址空间的值,变量值也被修改。

const 自定义数据类型(结构体、对象),也会分配内存空间。

#include <iostream>
#include <string>
using namespace std;
int main(void)
{
    int b = 200 ;
    const int a = b ;
    cout<<"a = "<< a <<endl;
    int *p = (int *) &a ;
    *p=2002;
    cout<<"*p = " << *p << endl;
    cout<<"a = "<< a <<endl;
}

运行结果

自定义类型(结构体)

#include <iostream>
#include <string>
using namespace std;

struct student{
    int num ;
    string name;
};
int main(void)
{
    const student Jack={100,"Jack"};
    cout<<"我是"<<Jack.num<<"号的"<<Jack.name<<endl;
    student *s = (student *)&Jack;
    s->num = 200 ;
    cout<<Jack.name<<"的号码改为:"<<Jack.num<<endl;
}

运行结果

const与#define的区别

1.编译器检查

const有类型,可以进行编辑器检查。#define无类型,不可进行类型检查。

在C++中用const 替换宏定义#define,因为宏定义在预处理阶段就将说有的标识符替换成对应的值。编译器编译时将不会出现宏定义的标识符。编译器如果报错会提示标识符出错,而不是值出错。

#include <iostream>
#include <string>
using namespace std;

#define MAX  3.14
const short mymax =1024 ;

void func(short i)
{
     cout<<"short i = "<< i <<endl;
}
void func(double i)
{
    cout<<"double i = "<< i <<endl;
}

int main(void)
{
   func(MAX);
   func(mymax);
}

 运行结果

 

2.作用域

宏的作用域是整个文件,const的作用域看定义位置/方式。

const有作用域,而#define不重视作用域,默认是定义出到文件结尾。如果定义在指定作用域下有效的常量,那么#define就不能用。

#include <iostream>
#include <string>
using namespace std;

void func(void)
{
    #define MAX  3.14
    const short mymax = 1024 ;
}
extern const int myint;
int main(void)
{
   cout<<"MAX = " << MAX << endl ;
//   cout<<"mymax = " <<mymax << endl ;//未声明的变量
}

运行结果

调用myint变量的编译结果 

 

 3.命名空间的成员

#define 不可以作为命名空间成员,const可以。

#include <iostream>
#include <string>
using namespace std;

namespace A {
    const int name_a = 100 ;
    #define MY_A 200
}

int main(void)
{
   cout<<"name_a = " << A ::name_a << endl ;
//   cout<<"MY_A = " << A ::MY_A << endl ;//不属于命名空间
   cout<<"MY_A = " << MY_A << endl ; //宏属于整个文件
}

运行结果

 以命名空间调用MY_A时的编译结果

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值