第一章:01从c语言到c++

本章学习目标:

1.bool类型

2.const限定符

3.const与#define

4.结构体内存对齐

1.1 bool类型

bool类型也称为逻辑型,其取值为true(逻辑真)和false(逻辑假),存储字节在不同编译系统中可能有所不同,Qt中为1个字节。

声明方式如下,可以将bool类型当作整数用,true一般为1,false为0

//此段代码为QtCreator开发工具,创建 Qt Console Application得到的main函数代码
//其中添加了定义bool变量以及读取bool变量大小的代码
#include <QCoreApplication>
#include <iostream>
#include <stdio.h>
using namespace::std;

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    bool testBool = true;              // 创建bool变量
    cout <<sizeof (testBool)<< endl;   // 读取bool大小 输出结果为 1

    return a.exec();
}

注意,将其它类型的值转为bool值时,非零值转换为true,零值转为false。

//此段代码为QtCreator开发工具,创建 Qt Console Application得到的main函数代码

#include <QCoreApplication>
#include <iostream>
#include <stdio.h>
using namespace::std;

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    bool testBool = bool (-1);
    cout << testBool << endl;   //输出结果 testBool = 1
    testBool = bool (0);
    cout << testBool << endl;   //输出结果 testBool = 0

    return a.exec();
}

1.2 const 限定符

const 是修饰变量的标识符,经过const修饰的变量就不能再改变了。所以也将const修饰的变量称为常变量。

定义的一般形式:

const   数据类型   常量名 = 常量值;    

数据类型  const   常量名  = 常量值;

例如:const  float  PI = 3.14159;

注意:常量在定义时必须初始化,常量在初始化后,不允许再被赋值。

#include <QCoreApplication>
#include <iostream>
using namespace::std;
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
   
    //const常变量,常变量的定义一定要初始化。
    //const int a; 这是一个错误写法,没有初始化
    const int aa = 10;
    // aa = 20;  这是个错误写法,常量不能重新被赋值
    //创建一个常量指针
    const int *p;  //const 在 * 左边,*p是常量,*p指向的值不能改变
    int b = 22;
    p = &aa;  // 将aa的地址赋值给p指针
    //*p = 22; 这是一个错误写法, // 取出p指针的值

    //const在*右边
    //int * const p2; 这是一种错误写法,p2为常量,在定义时先要赋值
    int * const p2 = &b;
    int c = 100;
    // p2 = &c; 这是一个错误写法
    *p2 = 200;
    cout << b<< endl;  //会发现b的值也发生了变化。

    return a.exec();
}

1.3 const与#define

const与#define的主要区别有以下几点:

1.const定义的常量有类型,而#define定义的没有类型,编译可以对前者进行类型安全检查,后者仅仅是做一个简单替换

2.const定义的常量在编译时分配内存,而#define定义的常量是在预编译时进行替换,不分配内存。

3.作用域不同,const定义的常量的作用域为该变量的作用域范围,而#define定义的常量作用域为它定义点到程序结束,当然也可以在某个地方用#undef取消

#include <QCoreApplication>
#include <iostream>

using namespace::std;
#define STR(a) #a    //#a是将a转为string
#define CAT(a,b) a##b   //a##b 是将ab合并起来

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    int xy = 200;
    cout << STR(ABCD) << endl;
    cout << CAT(x,y) << endl;


    return a.exec();
}

注意:定义常量还可以用enum,尽量用const、enum替换#define定义常量

//Effective C++ 3rd的一个例子
#define CALL_WITH_MAX(a,b) f((a) > (b) ? (a) : (b))

int a = 5;
int b = 0;
CALL_WITH_MAX(++a,b)     //a被累加两次
CALL_WITH_MAX(++a,b + 10)     //a被累加一次

1.4 结构体内存对齐

什么是内存对齐?

编译器为每个“数据单元”安排在某个合适的位置上。c,c++语言非常灵活,它允许你干涉“内存对齐”

为什么要对齐?

因为考虑到性能,在对齐的地址上访问数据快。

如何对齐?
第一步:第一个数据成员放在offset为0的位置,第二步:其他成员对齐至 #pragma pack 所指定的值的整数倍位置。

注意:整个结构体总大小对齐至各个成员中最大对齐数的整数倍。

#include <QCoreApplication>
#include <iostream>
#include <stdio.h>
using namespace::std;
#pragma pack(4)  //设置内存对齐数
struct Test
{
    char a;
    double b;
    char c;
};


//结构体中,第一个成员与结构体偏移量为0  &test == &test.a
//结构体中其他成员要对齐到对齐数的整数倍的地址
//结构体总大小为对齐数的整数倍
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    Test test;
    char * p = (char *)&test;

    cout << p <<endl;
    printf("p = %p\n",p);
    p = &test.a;
    cout << p <<endl;
    printf("p = %p\n",p);


    return a.exec();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值