复合类型

第4章 复合类型:C++让程序员能够使用基本的内置类型来创建更复杂的类型。最高级的形式是类(9~13章)。本章主要包括数组(存储多个同类型的值)、结构(存储多个不同类型的值)、指针(标识内存位置)。您还将学习如何创建和存储文本字符串及如何使用C风格字符数组和C++ string类来处理文本输入输出。最后,还将学习C++处理内存分配的方法,包括用于显式地管理内存的new和delete运算符。

4.1 数组

Demo
// arrayone.cpp -- small arrays of integers
#include <iostream>
int main()
{
    using namespace std;
    int yams[3];    // creates array with three elements
    yams[0] = 7;    // assign value to first element
    yams[1] = 8;
    yams[2] = 6;

    int yamcosts[3] = {20, 30, 5}; // create, initialize array
    // int yamcosts[3]; // not allowed
    // yamcosts = {20, 30, 5}; // not allowed

    // NOTE: If your C++ compiler or translator can't initialize
    // this array, use static int yamcosts[3] instead of
    // int yamcosts[3]

    cout << "Total yams = ";
    cout << yams[0] + yams[1] + yams[2] << endl;
    cout << "The package with " << yams[1] << " yams costs ";
    cout << yamcosts[1] << " cents per yam.\n";
    int total = yams[0] * yamcosts[0] + yams[1] * yamcosts[1];
    total = total + yams[2] * yamcosts[2];
    cout << "The total yam expense is " << total << " cents.\n";

    cout << "\nSize of yams array = " << sizeof yams;
    cout << " bytes.\n";
    cout << "Size of one element = " << sizeof yams[0];
    cout << " bytes.\n";

    // cin.get();
    return 0; 
}
(base) kimshan@MacBook-Pro output % ./"arrayone"
Total yams = 21
The package with 8 yams costs 30 cents per yam.
The total yam expense is 410 cents.

Size of yams array = 12 bytes.
Size of one element = 4 bytes.
初始化
// 赋值
int a[3] = {1,2,3};
// [1,2,3]
int b[3] = {1,2};
// [1,2,0]
int c[3] = {0};
// [0,0,0]

// 可以省略= (C++11)
int d[3] {1,2,3};
// [1,2,3]
int e[3] {0};
// [0,0,0]

4.2 字符串

参考:cstring

cin,遇到空白 (空格、制表符和换行符)代表输入结束
// strings.cpp -- storing strings in an array
#include <iostream>
#include <cstring>  // for the strlen() function
int main()
{
    using namespace std;
    const int Size = 15;
    char name1[Size];               // empty array
    char name2[Size] = "C++owboy";  // initialized array
    // NOTE: some implementations may require the static keyword
    // to initialize the array name2

    cout << "Howdy! I'm " << name2;
    cout << "! What's your name?\n";
    cin >> name1;
    cout << "Well, " << name1 << ", your name has ";
    cout << strlen(name1) << " letters and is stored\n";
    cout << "in an array of " << sizeof(name1) << " bytes.\n";
    cout << "Your initial is " << name1[0] << ".\n";
    name2[3] = '\0';                // set to null character
    cout << "Here are the first 3 characters of my name: ";
    cout << name2 << endl;
    // cin.get();
    // cin.get();
    return 0;
}
Howdy! I'm C++owboy! What's your name?
Charles
Well, Charles, your name has 7 letters and is stored
in an array of 15 bytes.
Your initial is C.
Here are the first 3 characters of my name: C++
cin.getline,遇到换行符代表输入结束,换行符可以被自动删掉
错误的输入案例
// instr1.cpp -- reading more than one string
#include <iostream>
int main()
{
    using namespace std;
    const int ArSize = 20;
    char name[ArSize];
    char dessert[ArSize];

    cout << "Enter your name:\n";
    cin >> name;
    cout << "Enter your favorite dessert:\n";
    cin >> dessert;
    cout << "I have some delicious " << dessert;
    cout << " for you, " << name << ".\n";
    // cin.get();
	// cin.get();
    return 0; 
}
(base) kimshan@MacBook-Pro output % ./"instr1"
Enter your name:
Jassica Windy
Enter your favorite dessert:
I have some delicious Windy for you, Jassica.
正确的
// instr2.cpp -- reading more than one word with getline
#include <iostream>
int main()
{
    using namespace std;
    const int ArSize = 20;
    char name[ArSize];
    char dessert[ArSize];

    cout << "Enter your name:\n";
    cin.getline(name, ArSize);  // reads through newline
    cout << "Enter your favorite dessert:\n";
    cin.getline(dessert, ArSize);
    cout << "I have some delicious " << dessert;
    cout << " for you, " << name << ".\n";
    // cin.get();
    return 0; 
}
(base) kimshan@MacBook-Pro output % ./"instr2"
Enter your name:
Jassica Windy
Enter your favorite dessert:
Cookie
I have some delicious Cookie for you, Jassica Windy.
cin.get,遇到换行符代表输入结束,换行符可以不被删掉,要再 get 一下
// instr3.cpp -- reading more than one word with get() & get()
#include <iostream>
int main()
{
    using namespace std;
    const int ArSize = 20;
    char name[ArSize];
    char dessert[ArSize];

    cout << "Enter your name:\n";
    cin.get(name, ArSize).get();    // read string, newline
    cout << "Enter your favorite dessert:\n";
    cin.get(dessert, ArSize).get();
    cout << "I have some delicious " << dessert;
    cout << " for you, " << name << ".\n";
    // cin.get();
    return 0; 
}
(base) kimshan@MacBook-Pro output % ./"instr3"
Enter your name:
Tony's Fu
Enter your favorite dessert:
Soup
I have some delicious Soup for you, Tony's Fu.
输入混合的字符串和数字(cin 会留一个回车在缓冲区)
// numstr.cpp -- following number input with line input
#include <iostream>
int main()
{
    using namespace std;
    cout << "What year was your house built?\n";
    int year;
    (cin >> year).get();
    // cin.get();
    cout << "What is its street address?\n";
    char address[80];
    cin.getline(address, 80);
    cout << "Year built: " << year << endl;
    cout << "Address: " << address << endl;
    cout << "Done!\n";
    // cin.get();
    return 0;
}
(base) kimshan@MacBook-Pro output % ./"numstr"
What year was your house built?
2022
What is its street address?
No1
Year built: 2022
Address: No1
Done!

4.3 string类简介

C++98 加入了 std::string。string 可以自动调整大小,char[]不可以。

char[] vs string
// Init
char array1[20]; // √
char array2[20] = "Hello"; // √
char array3[] = "Hello"; // √
char array4[20] = {"Hello"}; // √
char array5[] = {"Hello"}; // √

string str1 = "Hello"; √
string str2 = {"Hello"}; √

// Assign
array1 = array2;// x
str1 = str2; // √

// 拼接
str1 += str2; // √
// strtype2.cpp - assigning, adding, and appending
#include <iostream>
#include <string>               // make string class available
int main()
{
    using namespace std;
    string s1 = "penguin";
    string s2, s3;

    cout << "You can assign one string object to another: s2 = s1\n";
    s2 = s1;
    cout << "s1: " << s1 << ", s2: " << s2 << endl;
    cout << "You can assign a C-style string to a string object.\n";
    cout << "s2 = \"buzzard\"\n";
    s2 = "buzzard";
    cout << "s2: " << s2 << endl;
    cout << "You can concatenate strings: s3 = s1 + s2\n";
    s3 = s1 + s2;
    cout << "s3: " << s3 << endl;
    cout << "You can append strings.\n";
    s1 += s2;
    cout <<"s1 += s2 yields s1 = " << s1 << endl;
    s2 += " for a day";
    cout <<"s2 += \" for a day\" yields s2 = " << s2 << endl;

    //cin.get();
    return 0; 
}
(base) kimshan@MacBook-Pro output % ./"strtype2"
You can assign one string object to another: s2 = s1
s1: penguin, s2: penguin
You can assign a C-style string to a string object.
s2 = "buzzard"
s2: buzzard
You can concatenate strings: s3 = s1 + s2
s3: penguinbuzzard
You can append strings.
s1 += s2 yields s1 = penguinbuzzard
s2 += " for a day" yields s2 = buzzard for a day
string的其他操作,比如.size(class vs cstring)
// strtype3.cpp -- more string class features
#include <iostream>
#include <string>               // make string class available
#include <cstring>              // C-style string library
int main()
{
    using namespace std;
    char charr1[20]; 
    char charr2[20] = "jaguar"; 
    string str1;  
    string str2 = "panther";

    // assignment for string objects and character arrays
    str1 = str2;                // copy str2 to str1
    strcpy(charr1, charr2);     // copy charr2 to charr1
 
    // appending for string objects and character arrays
    str1 += " paste";           // add paste to end of str1
    strcat(charr1, " juice");   // add juice to end of charr1

    // finding the length of a string object and a C-style string
    int len1 = str1.size();     // obtain length of str1
    int len2 = strlen(charr1);  // obtain length of charr1
 
    cout << "The string " << str1 << " contains "
         << len1 << " characters.\n";
    cout << "The string " << charr1 << " contains "
         << len2 << " characters.\n";
    // cin.get();

    return 0; 
}
(base) kimshan@MacBook-Pro output % ./"strtype3"
The string panther paste contains 13 characters.
The string jaguar juice contains 12 characters.
cin.getline(charr, 20); vs getline(cin, str);
// strtype4.cpp -- line input
#include <iostream>
#include <string>               // make string class available
#include <cstring>              // C-style string library
int main()
{
    using namespace std;
    char charr[20]; 
    string str;

    cout << "Length of string in charr before input: " 
         << strlen(charr) << endl;
    cout << "Length of string in str before input: "
         << str.size() << endl;
    cout << "Enter a line of text:\n";
    cin.getline(charr, 20);     // indicate maximum length
    cout << "You entered: " << charr << endl;
    cout << "Enter another line of text:\n";
    getline(cin, str);          // cin now an argument; no length specifier
    cout << "You entered: " << str << endl;
    cout << "Length of string in charr after input: " 
         << strlen(charr) << endl;
    cout << "Length of string in str after input: "
         << str.size() << endl;
    // cin.get();

    return 0; 
}
(base) kimshan@MacBook-Pro output % ./"strtype4"
Length of string in charr before input: 0 
Length of string in str before input: 0
Enter a line of text:
qwertyuio
You entered: qwertyuio
Enter another line of text:
asdfghjkl
You entered: asdfghjkl
Length of string in charr after input: 9
Length of string in str after input: 9

4.4 结构简介

数组要求类型相同,结构可以是不同类型

Demo
// structur.cpp -- a simple structure
#include <iostream>
struct inflatable   // structure declaration
{
    char name[20];
    float volume;
    double price;
};

int main()
{
    using namespace std;
    inflatable guest =
    {
        "Glorious Gloria",  // name value
        1.88,               // volume value
        29.99               // price value
    };  // guest is a structure variable of type inflatable
// It's initialized to the indicated values
    inflatable pal = // C++里边可以不写成 struct inflatable pal
    {
        "Audacious Arthur",
        3.12,
        32.99
    };  // pal is a second variable of type inflatable
// NOTE: some implementations require using
// static inflatable guest =

    cout << "Expand your guest list with " << guest.name;
    cout << " and " << pal.name << "!\n";
// pal.name is the name member of the pal variable
    cout << "You can have both for $";
    cout << guest.price + pal.price << "!\n";
    // cin.get();
    return 0; 
}
(base) kimshan@MacBook-Pro output % ./"structur"
Expand your guest list with Glorious Gloria and Audacious Arthur!
You can have both for $62.98!
C++的结构体可以直接赋值!
// assgn_st.cpp -- assigning structures
#include <iostream>
struct inflatable
{
    char name[20];
    float volume;
    double price;
};
int main()
{
    using namespace std;
    inflatable bouquet =
    {
        "sunflowers",
        0.20,
        12.49
    };
    inflatable choice;
    cout << "bouquet: " << bouquet.name << " for $";
    cout << bouquet.price << endl;

    choice = bouquet;  // assign one structure to another
    cout << "choice: " << choice.name << " for $";
    cout << choice.price << endl;
    // cin.get();
    return 0; 
}
(base) kimshan@MacBook-Pro output % ./"assgn_st"
bouquet: sunflowers for $12.49
choice: sunflowers for $12.49
结构体数组
// arrstruc.cpp -- an array of structures
#include <iostream>
struct inflatable
{
    char name[20];
    float volume;
    double price;
};
int main()
{
    using namespace std;
    inflatable guests[2] =          // initializing an array of structs
    {
        {"Bambi", 0.5, 21.99},      // first structure in array
        {"Godzilla", 2000, 565.99}  // next structure in array
    };

    cout << "The guests " << guests[0].name << " and " << guests[1].name
         << "\nhave a combined volume of "
         << guests[0].volume + guests[1].volume << " cubic feet.\n";
    // cin.get();
    return 0; 
}
(base) kimshan@MacBook-Pro output % ./"arrstruct"
The guests Bambi and Godzilla
have a combined volume of 2000.5 cubic feet.

4.5 共用体

只能存一个元素的结构体,用 union 关键字


4.6 枚举

Demo
#include <iostream>
#include <climits>
#include <stdio.h>

enum spectrum
{
    red,
    orange,
    yellow,
    green,
    blue,
    violet,
    indigo,
    ultraviolt
};

int main()
{
    using namespace std;

    spectrum band;
    // 赋值给枚举
    band = blue; // √
    // band = 2; // x
    band = spectrum(2); // √

    // 枚举赋值给别人
    int num = band;
    cout << "num = " << num << ", band = " << band << endl; // num = 2, band = 2

    // enum spectrum1
    // {
    //     red,
    //     orange,
    //     yellow,
    //     green,
    //     blue,
    //     violet
    // };
    // 0,1,2,3,4,5
    // enum spectrum2
    // {
    //     red,
    //     orange,
    //     yellow = 10,
    //     green,
    //     blue,
    //     violet
    // };
    // 0,1,10,11,12,13

    spectrum r = red;
    spectrum b = blue;
    int c = r + b;           // √
    int d = spectrum(r + b); // √
    spectrum e = spectrum(r + b); // √

    return 0;
}

4.7 指针和自由存储空间

&取地址
// address.cpp -- using the & operator to find addresses
#include <iostream>
int main()
{
    using namespace std;
    int donuts = 6;
    double cups = 4.5;

    cout << "donuts value = " << donuts;
    cout << " and donuts address = " << &donuts << endl;
// NOTE: you may need to use unsigned (&donuts)
// and unsigned (&cups)
    cout << "cups value = " << cups;
    cout << " and cups address = " << &cups << endl;
    // cin.get();
    return 0; 
}
(base) kimshan@MacBook-Pro output % ./"address"
donuts value = 6 and donuts address = 0x7ff7b597c7f8
cups value = 4.5 and cups address = 0x7ff7b597c7f0
*解引用
// pointer.cpp -- our first pointer variable
#include <iostream>
int main()
{
    using namespace std;
    int updates = 6;        // declare a variable
    int * p_updates;        // declare pointer to an int

    p_updates = &updates;   // assign address of int to pointer

// express values two ways
    cout << "Values: updates = " << updates;
    cout << ", *p_updates = " << *p_updates << endl;

// express address two ways
    cout << "Addresses: &updates = " << &updates;
    cout << ", p_updates = " << p_updates << endl;

// use pointer to change value
    *p_updates = *p_updates + 1;
    cout << "Now updates = " << updates << endl;
    // cin.get();
    return 0; 
}
(base) kimshan@MacBook-Pro output % ./"pointer"
Values: updates = 6, *p_updates = 6
Addresses: &updates = 0x7ff7b51f67f8, p_updates = 0x7ff7b51f67f8
Now updates = 7
指针初始化,C++中 int* 本身是一种复合类型
// init_ptr.cpp -- initialize a pointer
#include <iostream>
int main()
{
    using namespace std;
    int higgens = 5;
    int * pt = &higgens;

    cout << "Value of higgens = " << higgens
         << "; Address of higgens = " << &higgens << endl;
    cout << "Value of *pt = " << *pt
         << "; Value of pt = " << pt << endl;
    // cin.get();
    return 0; 
}
(base) kimshan@MacBook-Pro output % ./"init_ptr"
Value of higgens = 5; Address of higgens = 0x7ff7b875b7f8
Value of *pt = 5; Value of pt = 0x7ff7b875b7f8
指针的危险
// 不要这样
long *p;
*p = 2333333; // 这样就会把不知道什么地方的值改成了2333333
new(C 里边的malloc,C++用 new)
// use_new.cpp -- using the new operator
#include <iostream>
int main()
{
    using namespace std;
    int nights = 1001;
    int * pt = new int;         // allocate space for an int
    *pt = 1001;                 // store a value there

    cout << "nights value = ";
    cout << nights << ": location " << &nights << endl;
    cout << "int ";
    cout << "value = " << *pt << ": location = " << pt << endl;

    double * pd = new double;   // allocate space for a double
    *pd = 10000001.0;           // store a double there

    cout << "double ";
    cout << "value = " << *pd << ": location = " << pd << endl;
    cout << "location of pointer pd: " << &pd << endl;
    cout << "size of pt = " << sizeof(pt);
    cout << ": size of *pt = " << sizeof(*pt) << endl;
    cout << "size of pd = " << sizeof pd;
    cout << ": size of *pd = " << sizeof(*pd) << endl;
    // cin.get();
    return 0;
}
(base) kimshan@MacBook-Pro output % ./"use_new"
nights value = 1001: location 0x7ff7bf9de7f8
int value = 1001: location = 0x7fcef4f06030
double value = 1e+07: location = 0x7fcef4f06040
location of pointer pd: 0x7ff7bf9de7e8
size of pt = 8: size of *pt = 4
size of pd = 8: size of *pd = 8
数组的 new 和 delete
// arraynew.cpp -- using the new operator for arrays
#include <iostream>
int main()
{
    using namespace std;
    double * p3 = new double [3]; // space for 3 doubles
    p3[0] = 0.2;                  // treat p3 like an array name
    p3[1] = 0.5;
    p3[2] = 0.8;
    cout << "p3[1] is " << p3[1] << ".\n";
    p3 = p3 + 1;                  // increment the pointer
    cout << "Now p3[0] is " << p3[0] << " and ";
    cout << "p3[1] is " << p3[1] << ".\n";
    p3 = p3 - 1;                  // point back to beginning
    delete [] p3;                 // free the memory
    // cin.get();
    return 0; 
}
(base) kimshan@MacBook-Pro output % ./"arraynew"
p3[1] is 0.5.
Now p3[0] is 0.5 and p3[1] is 0.8.

4.8 指针、数组和指针算数

Demo
  1. pw = pw + 1;如果pw 指向 double,+1一下地址+8,如果 pw 指向 short,+1 一下地址+2

  2. 数组和指针的区别来了!数组是常量,指针可以+1!

// addpntrs.cpp -- pointer addition
#include <iostream>
int main()
{
    using namespace std;
    double wages[3] = {10000.0, 20000.0, 30000.0};
    short stacks[3] = {3, 2, 1};

// Here are two ways to get the address of an array
    double * pw = wages;     // name of an array = address
    short * ps = &stacks[0]; // or use address operator
// with array element
    cout << "pw = " << pw << ", *pw = " << *pw << endl;
    pw = pw + 1;
    cout << "add 1 to the pw pointer:\n";
    cout << "pw = " << pw << ", *pw = " << *pw << "\n\n";

    cout << "ps = " << ps << ", *ps = " << *ps << endl;
    ps = ps + 1;
    cout << "add 1 to the ps pointer:\n";
    cout << "ps = " << ps << ", *ps = " << *ps << "\n\n";

    cout << "access two elements with array notation\n";
    cout << "stacks[0] = " << stacks[0] 
         << ", stacks[1] = " << stacks[1] << endl;
    cout << "access two elements with pointer notation\n";

    cout << "*stacks = " << *stacks
         << ", *(stacks + 1) =  " << *(stacks + 1) << endl;

    cout << sizeof(wages) << " = size of wages array\n";
    cout << sizeof(pw) << " = size of pw pointer\n";
    // cin.get();
    return 0; 
}
(base) kimshan@MacBook-Pro output % ./"addpntrs"
pw = 0x7ff7b86cd7e0, *pw = 10000
add 1 to the pw pointer:
pw = 0x7ff7b86cd7e8, *pw = 20000

ps = 0x7ff7b86cd7d6, *ps = 3
add 1 to the ps pointer:
ps = 0x7ff7b86cd7d8, *ps = 2

access two elements with array notation
stacks[0] = 3, stacks[1] = 2
access two elements with pointer notation
*stacks = 3, *(stacks + 1) =  2
24 = size of wages array
8 = size of pw pointer
输入字符串(静态)
// ptrstr.cpp -- using pointers to strings
#include <iostream>
#include <cstring>              // declare strlen(), strcpy()
int main()
{
    using namespace std;
    char animal[20] = "bear";   // animal holds bear
    const char * bird = "wren"; // bird holds address of string
    char * ps;                  // uninitialized

    cout << animal << " and ";  // display bear
    cout << bird << "\n";       // display wren
    // cout << ps << "\n";      //may display garbage, may cause a crash

    cout << "Enter a kind of animal: ";
    cin >> animal;              // ok if input < 20 chars
    // cin >> ps; Too horrible a blunder to try; ps doesn't
    //            point to allocated space

    ps = animal;                // set ps to point to string
    cout << ps << "!\n";       // ok, same as using animal
    cout << "Before using strcpy():\n";
    cout << animal << " at " << (int *) animal << endl;
    cout << ps << " at " << (int *) ps << endl;

    ps = new char[strlen(animal) + 1];  // get new storage
    strcpy(ps, animal);         // copy string to new storage
    cout << "After using strcpy():\n";
    cout << animal << " at " << (int *) animal << endl;
    cout << ps << " at " << (int *) ps << " " << &ps << endl;
    delete [] ps;
    return 0; 
}
(base) kimshan@MacBook-Pro output % ./"ptrstr"
bear and wren
Enter a kind of animal: snake
snake!
Before using strcpy():
snake at 0x7ff7b2c327e0
snake at 0x7ff7b2c327e0
After using strcpy():
snake at 0x7ff7b2c327e0
snake at 0x7faa28804080 0x7ff7b2c327c8
输入字符串(动态)
// newstrct.cpp -- using new with a structure
#include <iostream>
struct inflatable   // structure definition
{
    char name[20];
    float volume;
    double price;
};
int main()
{
    using namespace std;
    inflatable * ps = new inflatable; // allot memory for structure
    cout << "Enter name of inflatable item: ";
    cin.get(ps->name, 20);            // method 1 for member access
    cout << "Enter volume in cubic feet: ";
    cin >> (*ps).volume;              // method 2 for member access
    cout << "Enter price: $";
    cin >> ps->price;
    cout << "Name: " << (*ps).name << endl;              // method 2
    cout << "Volume: " << ps->volume << " cubic feet\n"; // method 1
    cout << "Price: $" << ps->price << endl;             // method 1
    delete ps;                        // free memory used by structure
    // cin.get();
    // cin.get();
    return 0; 
}
(base) kimshan@MacBook-Pro output % ./"newstrct"
Enter name of inflatable item: Cookie  
Enter volume in cubic feet: 20
Enter price: $100
Name: Cookie
Volume: 20 cubic feet
Price: $100
delete来释放内存,然后重新输入
// delete.cpp -- using the delete operator
#include <iostream>
#include <cstring>      // or string.h
using namespace std;
char * getname(void);   // function prototype
int main()
{
    char * name;        // create pointer but no storage
    name = getname();   // assign address of string to name

    cout << name << " at " << (int *) name << "\n";
    delete [] name;     // memory freed

    name = getname();   // reuse freed memory
    cout << name << " at " << (int *) name << "\n";
    delete [] name;     // memory freed again
    // cin.get();
    // cin.get();
    return 0;
}

char * getname()        // return pointer to new string
{
    char temp[80];      // temporary storage
    cout << "Enter last name: ";
    cin >> temp;
    char * pn = new char[strlen(temp) + 1];
    strcpy(pn, temp);   // copy string into smaller space

    return pn;          // temp lost when function ends
}
(base) kimshan@MacBook-Pro output % ./"delete"
Enter last name: Charles 
Charles at 0x7fcb09804080
Enter last name: Shan
Shan at 0x7fcb08f06030

4.9 类型组合

其实就是把上边的综合这些一个Demo
// mixtypes.cpp --some type combinations
#include <iostream>

struct antarctica_years_end
{
    int year;
 /* some really interesting data, etc. */
};

int main()
{
    antarctica_years_end s01, s02, s03; 
    s01.year = 1998;
    antarctica_years_end * pa = &s02;
    pa->year = 1999;
    antarctica_years_end trio[3]; // array of 3 structures
    trio[0].year = 2003;
    std::cout << trio->year << std::endl;
    const antarctica_years_end * arp[3] = {&s01, &s02, &s03};
    std::cout << arp[1]->year << std::endl;
    const antarctica_years_end ** ppa = arp; 
    auto ppb = arp; // C++0x automatic type deduction
// or else use const antarctica_years_end ** ppb = arp; 
    std::cout << (*ppa)->year << std::endl;
    std::cout << (*(ppb+1))->year << std::endl;
    // std::cin.get();
    return 0;
}
(base) kimshan@MacBook-Pro output % ./"mixtypes"
2003
1999
1998
1999

4.10 数组的替代品

vector
#include <iostream>
#include <vector>

int main()
{
    using namespace std;
    // 创建一个空的 vector 来存储整数
    vector<int> numbers;

    // 向 vector 添加一些元素
    numbers.push_back(10);
    numbers.push_back(20);
    numbers.push_back(30);
    numbers.push_back(40);
    numbers.push_back(50);

    // 输出 vector 中的元素
    cout << "Vector contains:" << endl;
    for (int i = 0; i < numbers.size(); ++i)
    {
        cout << "Element at index " << i << ": " << numbers[i] << endl;
    }

    // 使用迭代器来访问 vector 中的元素
    cout << "Accessing elements using iterators:" << endl;
    for (vector<int>::iterator it = numbers.begin(); it != numbers.end(); ++it)
    {
        cout << *it << " ";
    }
    cout << endl;

    // 修改 vector 中的元素
    numbers[2] = 300; // 将索引为 2 的元素修改为 300

    // 再次输出 vector 中的元素,查看修改结果
    cout << "After modification, vector contains:" << endl;
    for (int number : numbers)
    {
        cout << number << " ";
    }
    cout << endl;

    // 删除 vector 中的最后一个元素
    numbers.pop_back();

    // 输出 vector 中的元素数量
    cout << "The vector now contains " << numbers.size() << " elements." << endl;

    return 0;
}
(base) kimshan@MacBook-Pro output % ./"test1"
Vector contains:
Element at index 0: 10
Element at index 1: 20
Element at index 2: 30
Element at index 3: 40
Element at index 4: 50
Accessing elements using iterators:
10 20 30 40 50 
After modification, vector contains:
10 20 300 40 50 
The vector now contains 4 elements.
array
// choices.cpp -- array variations
#include <iostream>
#include <vector>   // STL C++98
#include <array>    // C++0x
int main()
{
    using namespace std;
// C, original C++
    double a1[4] = {1.2, 2.4, 3.6, 4.8};
// C++98 STL
    vector<double> a2(4);   // create vector with 4 elements
// no simple way to initialize in C98
    a2[0] = 1.0/3.0;
    a2[1] = 1.0/5.0;
    a2[2] = 1.0/7.0;
    a2[3] = 1.0/9.0;
// C++0x -- create and initialize array object
    array<double, 4> a3 = {3.14, 2.72, 1.62, 1.41};  
    array<double, 4> a4;
    a4 = a3;     // valid for array objects of same size
// use array notation
    cout << "a1[2]: " << a1[2] << " at " << &a1[2] << endl;
    cout << "a2[2]: " << a2[2] << " at " << &a2[2] << endl;
    cout << "a3[2]: " << a3[2] << " at " << &a3[2] << endl;
    cout << "a4[2]: " << a4[2] << " at " << &a4[2] << endl;
// misdeed
    a1[-2] = 20.2;
    cout << "a1[-2]: " << a1[-2] <<" at " << &a1[-2] << endl;
    cout << "a3[2]: " << a3[2] << " at " << &a3[2] << endl;
    cout << "a4[2]: " << a4[2] << " at " << &a4[2] << endl;
    //  cin.get();
    return 0;
}
(base) kimshan@MacBook-Pro output % ./"choices"
a1[2]: 3.6 at 0x7ff7b52d77e0
a2[2]: 0.142857 at 0x7f8f71004090
a3[2]: 1.62 at 0x7ff7b52d77a0
a4[2]: 1.62 at 0x7ff7b52d7780
a1[-2]: 20.2 at 0x7ff7b52d77c0
a3[2]: 1.62 at 0x7ff7b52d77a0
a4[2]: 1.62 at 0x7ff7b52d7780

最后更新于

这有帮助吗?