QT软件实习笔记1

2024.1.13

上午

 1.课堂练习一

键盘上输入一个人的年龄,并且输出;用自己习惯的开发环境

#include 

int main() {
    int age;
    std::cout << "请输入您的年龄:";
    std::cin >> age;
    std::cout << "您的年龄是:" << age << std::endl;   
 return 0;
}

QT软件实习笔记1_第1张图片

问题:
开发环境(win):

1. vs 2019(比最新版本第一个版本);

2.Dve C++ 5.11;

3.clion

需要注意的点:

1. 目录或文件命名时,不要使用中文:使用中文可能没有问题,使用英文一定没有问题:

2. #include 和具体头文件用空格间隔;#include  

3. 变量命名时,不要使用a,b,c等,更不要使用拼音:见名知意:做上线项目时,遇到

某些变量名,不知英文,查一下英文表示;

4. 一个变量没有有效值时(如需从键盘输入):此时需要给这个变量赋值,用相应类型的

〝零值”赋给它;

  1. 整数类;int最常用,效率也最高
  2. 实数类;
  3. 字符类;

5. 测试边界问题:就是输入数据的范围:有几种可能性,就要有几种测试:

6. 当声明多个变量时,无论这些变量是否属于同种类型,是简单变量还是指针变量,还是数组,一个变量占一行:如果变量没有有效值,都要赋相应类型的零值;(对应第三题的时候,注意不同版本语言的语法变更)

如是数组,将数组中的每个元素赋以相应类型的零值;

参考代码:

void test ();
int main() {
    printf("\n");
    test();
    printf("\n");
    return 0;
}
void test() {
    int age = 0;
    cout << "input age : ";
    cin >> age;
    printf("\n");
//输入数据的有效性检查
if (age < 1){
    cout << "年龄小于等于0,无效!" << endl;
    //return;
} else if (age > 120) {
    cout << “年龄大于120,无效!" << endl;
} else {
    cout << "age = m << age << endl;
}
}

 2.课堂练习二

    有一个数组,用来存放1-9之间的数字,计9个元素,int numbers[9]={4,1,3,2,6,5,8,9,};从1~9中,将数组中的7找出来;

#include 
using namespace std;

int main() {
    int numbers[9] = {4, 1, 3, 2, 6, 5, 8, 9};
    int target = 7;
    bool found = false;

    for (int i = 0; i < 9; i++) {
        if (numbers[i] == target) {
            found = true;
            break;
        }
    }

    if (found) {
        cout << "数字7在数组中找到了!" << endl;
    } else {
        cout << "数字7在数组中未找到。" << endl;
    }

    return 0;
}
1.第一种方式(参考代码):
#include 
using namespace std;
void test();
int main() {
    printf("\n");
    test();
    printf("\n");
    return 0;
}
void test() {
    int sum1 = 0;
    int sum2 = 0;
    int numbers[9] = {4, 1, 3, 2, 6, 5, 8, 9,};
   //在循环这类操作中,计数器可使用简单变量名:i,j,k等;
    for (int i = 1; i < 10; ++i) {
        sum1 += i;
    }
    for (int i = 0; i < 9; ++i) {
        sum2 += numbers[i];
    }
    int result = sum1 - sum2;
    cout << "result -> " << (result) << endl;
}
2.第二种方式(参考代码):(在C语言或C++的运算符中,有二进制运算符;)
  1. 二进制的“左移”和“右移”;
  2. 二进制“非”
  3. 二进制“异或”
  4. 二进制“或”
  5. 二进制“与”
#define Max 9
void test() {
    int numbers[Max] = {4, 1, 3, 2, 6, 5, 8, 9,};
    int result = 0;
    for (int i = 1; i < 10; ++i) {
        result ^= i;
    }
    for (int i = 0; i < Max; ++i) {
        result ^= numbers[i];
    }
    cout << "result -> " << (result) << endl;
}

3.课堂练习三

有一个正整数12345,求它的二进制表示;后面扩展为16进制;

经查询资料,我们可以使用bitset库来进行二进制转换。bitset<32>(num)将整数num转换为一个32位的二进制数,然后使用to_string()方法将其转换为字符串表示。

#include 
#include 
using namespace std;

int main() {
    int num = 12345;
    string binary = bitset<32>(num).to_string();
    cout << binary << endl;
    return 0;
}

或者定义一个函数decimalToBinary,将十进制数转换为二进制字符串。

#include 
#include 

std::string decimalToBinary(int decimal_num) {
    std::string binary_str = "";
    
    while (decimal_num > 0) {
        int remainder = decimal_num % 2;
        binary_str = std::to_string(remainder) + binary_str;
        decimal_num /= 2;
    }
    
    return binary_str;
}

int main() {
    int decimal_num = 12345;
    std::string binary_str = decimalToBinary(decimal_num);
    
    std::cout << "Binary: " << binary_str << std::endl;
    
    return 0;
}
  1. 转换的概念:对于将10进制到N进制的转换(值大小不变,只是换种方式表示);
  2. 转换方式:除以N,取余,反写
  3. 具体;
    1. 数组方式;
    2. 自定义数据结构方式;
    3. 预定义的STL模板方式;stack
      1. push,进栈、入栈、压栈;
      2. top,显示头元素;
      3. pop,出栈,弹栈;
      4. empty,判断栈是否为空;
  4. 思路:将余数入栈,值缩小2倍;循环直到值为0;当栈非空,不断弹栈,得到结果;
参考代码:
void test() {
    int number = 12345;
    cout<<" number -> "<<(number)< bin;
    while (number) {
        int mod = number % 2;
        bin.push(mod);
        number /= 2;
    }
    while (!bin.empty()) {
        cout<

4.课堂练习四

将练习3中的2进制改为16的转换;a,b,c,d,e,f | A,B,C,D,E,F; 

在C语言或C++中,关于布尔类型之“真假”问题。

  1. 在C语言中,对于真假,遵循一个原则进行条件判断:“非零为真”;
  2. 到了C++中,有了布尔类型;bool => false | true; 但因为C++兼容C语言,所以仍然支持非零为真;
参考代码:

注意整数到字母的转换

在C++中,是一个头文件,它提供了一些用于输入和输出的函数和宏定义。使用头文件可以方便地进行文件的读写操作、格式化输出和输入等。

#include 
#include 
#include 
using namespace std;
void test();
int main() {
    printf("\n");
    test();
    printf("\n");
    return 0;
}
void test() {    
   int x = 12345;
   cout<<"x= "< bin;
   while(x){
   		int mod = x % 16; // 0~15 '0' 整数0与字符0之间存在 '0'=0+48 
if(mod<10){
   			bin.push(mod+48);
		}else{//10-15  'a'
			bin.push(mod+'a'-10);  // 11: 1+'a'
		}  
		x/=16; 	
   }
   while(!bin.empty()){
   		printf("%-2c",bin.top());
   		bin.pop();
   }    
}

下午:

5.有用的关键字auto

  1. 最早起源于C 语言,存在感非常低,实际上处于省路狀态;到了C++的11 版本之后,对回
    此关键字进行了改造,让其具有“类型推断"的功能;
  2. 如何类型推断?对某个变量的数据类型进行推断,推断这个变量是什么类型?这个变量是
    慰了初值的;
void test() {
    auto a = 12;
    cout << "typeid(a) -> " << typeid(a).name() << endl;
    auto b = 12L;
    cout << "typeid(b) -> " << typeid(b).name() << endl;
    auto c = 12LL;
    cout << "typeid(c) -> " << typeid(c).name() << endl;
}

(对复杂布局进行推断)

6.指针

  1. 指针是指针变量的简称,从某个角度上说,指针变量与整型变量没有区别:大家都是变量,都有值,值都会放在内存中;
  2. 既然是变量,它就要保存数据:与整型变量 age 所表示的整数值不同;指针变量保存的是
    地址值;
  3. 地址值是什么,(地址是字节的编号a,&a)变量的内存地址
  4. 电脑内存

win——我的电脑 -》右键-〉属性:

QT软件实习笔记1_第2张图片

mac——设置-》通用-〉关于

QT软件实习笔记1_第3张图片

1 kb = 1024 byte

1 mb = 1024 kb

1 gb = 1024 mb

1 tb = 1024 gb

16*1024*1024*1024 bytes

void test() {
    int a = 110;
    cout << " a -> " << (a) << endl;
    cout << "&a -> " << (&a) << endl;
    //存放地址值的变量,就是指针变量;
    int *pa = &a; //&取地址运算符;从变量到地址
    cout << "pa -> " << (pa) << endl;
    int b = *pa; //* 解引用运算符;从地址到变量;
    cout << "b -> " << (b) << endl;
}

QT软件实习笔记1_第4张图片

7.指针的三个用途:

指向,就是指针变量,保存了什么变量的地址;就说这个指针变量指向了谁。
  1. 指向单个变量;就是保存了变量的地址;
    1. 复杂变量(类或结构对象);
    2. 简单变量;内置类型;
  2. 指向数组;就是指针保存了数组的地址;
  3. 指向函数;就是指针保存了函数的地址;函数指针;
在C++中的结构与类几乎没有区別,只在访问级别有所不同;

(在结构中,没有访问级别,标明为公有;在类时为私有)

在C++中,结构体和类是两种用于定义自定义数据类型的关键字。它们之间的主要区别如下:

  1. 1. 成员默认访问权限在结构体中,默认的成员访问权限是公共的(public),而在类中,默认的成员访问权限是私有的(private)。

  2. 2. 成员函数在结构体中,可以定义成员函数,但是默认情况下,结构体的成员函数是公共的(public)。而在类中,成员函数默认是私有的(private)。

  3. 3. 继承:结构体可以继承自其他结构体或类,也可以作为基类被其他结构体或类继承。而类可以继承自其他类,也可以作为基类被其他类继承。

  4. 4. 默认构造函数:在结构体中,如果没有显式定义构造函数,编译器会自动生成一个默认构造函数。而在类中,如果没有显式定义构造函数,编译器也会自动生成一个默认构造函数。

  5. 5. 默认析构函数:在结构体中,如果没有显式定义析构函数,编译器会自动生成一个默认析构函数。而在类中,如果没有显式定义析构函数,编译器也会自动生成一个默认析构函数。

  6. 6. 类型转换:结构体和类都可以进行类型转换,但是在类中,可以通过重载类型转换运算符来自定义类型转换的行为。

  7. 7. 使用习惯:一般来说,结构体用于表示一组相关的数据,而类用于表示一个对象的属性和行为。

  8. 课堂练习5

QT软件实习笔记1_第5张图片

利用上述的半成品代码,进行以下的练习;

1. 将声明的显示学生对象的函数 showStudent 实现;

2. 将对象stu1进行赋值并输出;

3. 通过指针变量pst向堆区申请内存,并给分量赋值后输出;

参考代码:
struct Student {
    int id;
    char name[41];
    int age;
    int scores[3];
};
void showStudent(const Student *stu);
Student input();
void test() {
    Student student = input();
    printf("\n");
    showStudent(&student);
}
void showStudent(const Student *stu) {
    //if (stu == nullptr) {
    if (!stu) {
        return;
    }
    printf("Student{%d,\"%s\",%d,[%d,%d,%d]}\n", stu->id,
           stu->name, stu->age, stu->scores[0], stu->scores[1],
           stu->scores[2]);
}
Student input() {
    Student std;
    cout << "input id: ";
    cin >> std.id;
    //getchar();
    cin.get(); //接受键盘缓冲区中遗留的字符,这里为换行符
    cout << "input name: ";
    cin.getline(std.name, sizeof(std.name));
    cout << "input age: ";
    cin >> std.age;
    cout << "input three scores: ";
    cin >> std.scores[0] >> std.scores[1] >> std.scores[2];
    return std;
}

(getchar()=C++中的cin.get()接受键盘缓冲区中遗留的字符,这里为换行符)

4. 结构指针变量,使用堆区(heap)内存;堆区内存使用考虑以下四点;(Stack栈提供指令)

  1. 申请;new | malloc
  2. 检测;
  3. 使用;
  4. 释放;delete | free
void test() {
    Student *pst = nullptr;
    //1.申请;向银行贷款
    pst = new Student;
    //2、检测;贷款是否成功
    if (!pst) {
        cout << "内存申请失败" << endl;
        return;
    }
    //3、应用;可以用贷款干事;
    *pst = input();
    printf("\n");
    showStudent(pst);
    //4、释放;向银行返还贷款
    delete pst;
    pst = nullptr;
}

9. C++中的运算符重载

C++中运算符的重载有何优点?操作类或结构对象时 (直观);

在C++运算符重载功能,我们必须要掌握的两类运算符;

  1. 比较运算符;与排序有关;
  2. 输入(>>)、输出(<<)运算符;与输入、输出有关;
  3. 为何整数可以直接输出,而自定义的结构或类对象不可以?   因为int,double等类型是语言内置的,它可以用于代码的任何角落,cout或cin这些运算符支持(认识内置类型);而自定义类型,编译器或运算符不认识,也不会支持;所以是不能输入或输出自定义类型对象的;
  4. 因为直接输入和输出是比较直观的,我们想像输出内置类型变量一样,输出自定义对象;就要让编译器或cout/cin认识我们自定义的对象;如何认识?在类或结构中,需要重载输入和输出运算符;
  5. 理论上说,默认一个结构或类,都(每一个!)要有自己的输入、输出运算符重载;

struct Value {
  int value;
  friend ostream &operator<<(ostream &out, const Value &obj) {
     return out << "Value{" << obj.value <<"}";
     }
  friend istream &operator>>(istream &in, Value &obj) {
     return in >> obj.value;
     }
};
  1. #include 
    #include 
    #include 
    #include 
    using namespace std;
    void test();
    int main() {
        printf("\n");
        test();
        printf("\n");
        return 0;
    }
    struct Student {
        int id;
        char name[41];
        int age;
        int scores[3];
    };
    struct Value {
        int value;
        friend ostream &operator<<(ostream &out, const Value &obj) {
            out << "Value{" << obj.value << "}";
            return out;
        }
        friend istream &operator>>(istream &in, Value &obj) {
            in >> obj.value;
            return in;
        }
    };
    void test() {   
        Value v1{10};
        cout << v1 << endl;
        printf("\n");
        cout << "input v1: ";
        cin >> v1;
        cout << v1 << endl;
    }

    作业

  1. 针对结构Student,完成学生对象的输入和输出;重载后,可以执行如下的操作;

QT软件实习笔记1_第6张图片

//  main.cpp
//  QT1.13


#include 
using namespace std;
struct Student
{
    int id;
    char name[41];
    int age;
    int scores[3];
    friend ostream &operator<<(ostream &out,Student &s)
    {
        out<<"Student ID:"<>(istream &in,Student &s)
    {
        in>>s.id;
        in>>s.name;
        in>>s.age;
        for(int i = 0;i < 3;i++)
            in>>s.scores[i];
        return in;
    }
};

void Student_Operator()
{
    Student s;
    cout<<"请输入对应学生学号:";
    cin>>s.id;
    cin.get();
    cout<<"请输入对应学生姓名:";
    cin.getline(s.name,sizeof(s.name));
    cout<<"请输入对应学生年龄:";
    cin>>s.age;
    cout<<"请依次输入对应学生三科成绩:";
    cin >> s.scores[0] >> s.scores[1] >> s.scores[2];
    cout<<"学生信息如下:"<

QT软件实习笔记1_第7张图片

2. 针对示例的Value类,进行 + 和 – 这两个运算符进行重载,能够直观的表示两个Value对象的如下操作;

QT软件实习笔记1_第8张图片

//
//  main.cpp
//  QT1.13
//
//  Created by sofia  on 2024/1/14.

#include 
using namespace std;

struct Value
{
    int value;
    
    Value operator+(Value &v)
    {
        Value temp;
        temp.value = this->value + v.value;
        return temp;
    }
    
    Value operator-(Value &v)
    {
        Value temp;
        temp.value = this->value - v.value;
        return temp;
    }
    
    Value operator*(Value &v)
    {
        Value temp;
        temp.value = this->value * v.value;
        return temp;
    }
    
    Value operator/(Value &v)
    {
        Value temp;
        temp.value = this->value / v.value;
        return temp;
    }
    
    bool operator>(Value &v)
    {
        return this->value > v.value;
    }
    
    bool operator<(Value &v)
    {
        return this->value < v.value;
    }
    
    friend ostream &operator<<(ostream &out,Value &v)
    {
        out << v.value << endl;
        return out;
    }
    
    friend istream &operator>>(istream &in,Value &v)
    {
        in >> v.value;
        return in;
    }
    
    friend ostream &operator<<(ostream &out, bool b)
    {
        out << (b ? "true" : "false") << endl;
        return out;
    }

};

int main()
{
   Value v1, v2;

   cout << "请依次输入Value值:";
   cin >> v1 >> v2;

   Value sum = v1 + v2;
   Value difference = v1 - v2;
   Value product = v1 * v2;
   Value quotient = v1 / v2;
   bool greater = v1 > v2;
   bool less = v1 < v2;

   cout << "Sum: " << sum << endl;
   cout << "Difference: " << difference << endl;
   cout << "Product: " << product << endl;
   cout << "Quotient: " << quotient << endl;
   cout << "Greater: " << greater << endl;
   cout << "Less: " << less << endl;

   return 0;
}

QT软件实习笔记1_第9张图片

这里的0,1表示false,ture

你可能感兴趣的:(笔记,qt,软件工程)