第四章 复合类型

4.2 数组

定义 int arrName[size] 定义一个int 型的数组,数组长度为size;其中size必须为常量不能是变量。

例: int arr[10]

初始化:

int arr[] = {11, 12, 13, 14, 15};  初始化为大小为5的数组。

int arr1[20] = {32, 33}; 剩下未初始化的18个编译器自动赋值0;

所以int arr2[10] = {0}; 可以将arr 全部初始化为0.

sizeof(arr):输出整个arr数组占用的字节空间,即4 * 5 = 20

sizeof(arr[0]) : 输出arr第一个下标 int型占用的字节大小,为4

数组未初始化,值是不确定的,即之前内存保存的数值

c++ 11 新增初始化话方法

int arr[10] {}; //可以不加 = 号; {} 中可以没有任何值,编译器全部初始化为0

字符串数组:

  char arrstr[] = "HelloWorld!"; 长度未12 会自动加上结束符\0
  char arrStr1[10] = {'a', 'b', 'b', 'v', 'b', 'f', 'h' }; 不是字符串
  char arrStr1[10] = {'a', 'b', 'b', 'v', 'b', 'f', '\0' };是字符串

strlen() 为函数,计算字符串长度不包括\0

  cin >> name;
  cout << "Entor food: "  << endl;
  cin >> food;
  cout << "name : " <<name << endl;
  cout << "food : " <<food << endl;
如果直接输入的是 zhangsan apple
输出 name:zhangsan
     food:apple
cin 先从输入流中读取zhangsan,加上\0,放入name数组中;然后读取apple,加上\0,放到food中。

getline()和get()函数

cin.getline(strline, 50); 将输入流的一行放入数组strline中,最多50字节。会将换行符替换为\0;

cin.get(strline, 50);  将输入流的一行放入数组strline中,最多50字节。不会替换换行符,换行符不会读取还是在输入流中,所以在此调用cin.get() 读取到的是换行符。

#include <stdio.h>
#include <stdlib.h>
#include <iostream>

using namespace std;

void start_array_text_fun();

int main()
{
    cout << "Start main funtion!" << endl;
    start_array_text_fun();
    system("pause");    // 防止运行后自动退出,需头文件stdlib.h
    return 0;
}

void start_array_text_fun() {
  int arr[] = {11, 12, 13, 14, 15};
  int arr1[20] = {32, 33};
  cout << "arr size: " << sizeof(arr) << endl;
  cout << "arr size: " << sizeof arr[0] << endl;
  cout << "arr : " << *(arr+1) << endl;

  char arrstr[] = "HelloWorld!";
  cout << "arrstr : " << arrstr << endl;
  cout << "sizeof arrstr : " << sizeof arrstr << endl;
   int size = 20;
  char arrnamr[size] = {'h', 'b'};
  cout << "arrnamr : " <<sizeof arrnamr << endl;

  char strline[100];
  cin.getline(strline, 50);
  cout << strline << endl;

}

4.3 string类型

string 为c++类

string str = “HelloWorld!”; 定义string类型的对象str,并赋值;str是实例化的对象

str.size() 计算长度,单位字节,不带\0

str1 += str2;连接两个字符串

str1 = str2;将str2 内容赋值到str1

strncpy(des, src)c风格的字符串赋值

strncat(char1, char2)c风格的字符串连接

4.4 结构体

定义结构体:

  struct st_student {

    char name[20];

    int age;

    int high;

  };

定义结构体变量:

  struct st_student stu1 = {"zhangsan", 10, 168};

  st_student stu2 = {"lisi", 17, 178};

C++ 允许,定义结构体不加struct 关键字;c语言必须加;c语言可以通过typedef 关键字定义别名方法省略struct关键字。

初始化:

结构体初始化方式和数组类似

  struct st_student stu1  {"zhangsan", 10, 168}; //可以省略 = 号

struct st_student stu1  {}; //括号没有值,将被初始化为全0

结构体赋值 stu1 = stu2;将stu2 所有成员赋值给stu1; 注意数组是不能直接这样赋值的

  struct {

    char name[20];

    int age;

    int high;

  } stu;  定义一种结构体,没有名字,并定义变量stu,以后不能再定义其他的此种类型变量。

结构体的位字段:

  struct bit_register {
    unsigned int SN : 4;  位字段,表示占用4bit
    unsigned int  : 4;
    bool power : 2;
    bool enable : 1;
    bool IN : 1;
  } regist;

4.5 共同体

union id {
 int identify;
 char inden[10];
};
共用体的成员共用一块内存,所以同一时间只能存储一个成员,整个共用体的内存大小是共用体最大的成员占用的内存。
共用体是为了节省内存
匿名共用体
union wigdth {
    int high;
    char name[10];
    union  {
    int identify;
    char inden[10];
    } prize;
};
由于union没有名字,所以调用是省略共用体名字:prize.identify

4.6 枚举类型

enum 提供了创建常量的一种方法,可以取代 const

enum weekday {Monday, Tuesday,Wednesday, Thursday, Friday};

其中 成员Monday都是枚举常量,代表从0 开始的整数

可以定义枚举变量  weekday day = Tuesday;

枚举变量必须用常量做初始化。

也可以自定义初始化

enum weekday {Monday = 1, Tuesday,Wednesday = 100, Thursday, Friday};

4.7 指针和自由存储空间

计算机存储数据三个基本要素:

                                                1 信息存储在何处

                                                2 存储的值

                                                3 存储数据类型

指针声明:

 int* p; 声明指针变量p 为指向int型的指针,指针p中存储的地址是一个int型数据的地址

p是 int* 型指针或int* 型,*p 是int型

int a = 1;

int* p = &a; 初始化,将a的地址保存到指针变量p

 指针的真正用途:在运行阶段分配未命名的内存以存储值。

new运算符:

int* pn = new int; new根据类型int。自己找到一个长度正确的内存块,返回给pn。

通用格式:typename* pointer_name = new typename ; 
//typename可以是基本类型,也可以是结构等。

int a;局部变量存储在函数栈内,包块指针pn;但是new 申请的内存和malloc函数一样,是存储在堆(heap)上或自用存储区的内存区域。

delete运算符

int* ps = new int;
delete ps; 释放ps指向的内存

注意:必须配对使用new 、delete;出现new 一定要有delete,避险造成内存泄漏。

delete不能重复释放;不能释放声明的变量:int ia = 10;delete ia;//不合法

动态数组

int arr[10]; //静态联编,系统在编译阶段创建一个静态数组,内存也是在编译阶段分配。
int* parr = new int[10]; //动态联编,系统在运行阶段为数组创建内存。 数组长度可以动态选择。

parr[1]; 等价于 *(parr + 1);
delete [] parr; 释放数组

注意:

      1 不能使用delete释放不是new的内存

      2 不能使用delete释放通意块内存两次

      3 使用new[] 申请的内存,要用delete[] 释放内存

指针数组,数组地址

 int arr[10] = {1,2,3,4,5,6,7,8,9,10};

arr 代表数组第一个元素的地址,等价于 &arr[0] ,  arr +1 相当于将指针移向第二个元素,即地址加上指针类型int的内存大小。可以将arr当作 int* 型

&arr 为整个数组的地址,&arr +1 相当于将指针移动到下一个int[10] 的数组,即&arr +1 == arr + sizeof(int)* 10; &arr可以当作 int[10] * 型,即指向10个int数据大小的数组的指针。

定义数组指针 int (*p)[10] = &arr;  //p是一个数组指针,p指向大小为10 的int型数组。

注意数组大小[10] 必须指定,因为编译器必须知道,这个指针是指向多大的数组的。

所以*p == *(&arr)== arr; **p == arr[0] == *(arr+0) ; *(*p +1) == *(arr +1) 

创建动态数组:

struct thing {

    int good;

    int bad;       

};

thing* p = new thing;

利用指针引用成员: p->good;

自动存储、静态存储、动态存储

自动存储:就是函数局部变量所占用的内存,在函数栈上,函数结束时会自动释放,作用域为大括号范围,大括号结束时释放。内存释放和申请顺序相反,后进先出。

静态存储:函数外定义和函数内且使用static声明的变量称为静态存储变量,生命周期为整个程序周期,存储在静态存储区域。

动态存储:使用new (c的 malloc)申请的内存称为动态存储,程序在堆中申请内存,可以delete动态的释放。如果不及时delete 会造成内存泄漏。

指针数组:

thing mthing1; 

thing mthing2; 

const thing * arrthing[2] = { mthing1, mthing2};

thing ** p = arrthing;

arrthing 是一个指针数组,数组里存储的都是thing*型指针,引用成员:arrthing[0]->good;

p是一个指向指针数组的指针,因为p指向arrthing的第一个成员mthing1地址,mthing1是一个thing*型,所以p要声明成指向thing*型的指针,即thing** p;

引用成员,*(p+1)->bad; 等价于 arrthing[1]->bad;

vector、array

vector:

vector是STL的动态数组,属于模板类,可以在运行中根据需要改变数组的大小。因为它以数组的形式储存,所以它的内存空间是连续的。vector的头文件为#include<vector>

定义一个动态数组: vector<int> arr(100); arr 是一个vector<int>型,内部有100个int数据

可以向数组一样使用 arr[10] = 10;

常用方法:

1.vector<int>a                                  创建一个动态数组a,a的默认初值为0

2.vector<int >b(a)                             将a中的元素复制到b中

3.vetcor<int>a(100)                          将数组a的元素定义为100个,默认初始值为0

4.vector<int>a(100,6)                       定义100个值为6的元素

5.vector<string>a(10,"null")              定义10个值为null的元素

6.vector<string>a(10,"hello")             定义10个值为hello的元素

7.vector<string>b(a.begin(),a.end())  将动态数组a的元素值复制到b中

常用操作:

1.a.push_back(100)                            在尾部加入一个值为100的元素

2.a.size()                                              返回数组中元素的个数

3.bool isEmpty=a.empty()                    判断a是否为空,若为空返回true,若不为空则返回false

4.cout<<a[0]<<endl                               输出数组的大小

5.a.insert(a.begin+i,k)                           在第i个元素前插入k

6.a.insert(a.end(),10,5)                         在末尾插入10个值为5的元素

7.a.pop_back                                        删除末尾元素

8.a.erase(a.begin()+i,a.begin()+j)         将[i,j-1]的元素都删除

9.a.erase(a.begin()+i)                           将第i+1个元素删除

10.a.resize(n)                                        将数组重置为n个元素

11.a.clear()                                             清空数组

12.reverse(a.begin(),a.end())                 将数组逆转

13.sort(a.begin(),a.end())                       将数组从小到大排序

array:

vector 是在堆中动态申请内存,程序自动释放;效率相比数组要低;

array和数组一样,再栈中申请内存。

定义方法 array<int, 10> arr; 创建大小为10的 int array 对象。第二个参数是固定的不能是变量。

所有array对象的大小是固定的。

array 模板类可以直接赋值,arr1 = arr2;注意 数组是不可以的,只能一个一个复制;

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值