一维数组和C字符串
数组基础
- 数组是用来存储同类型变量的数据集合
- 一个数组中的元素可以用下标来访问
声明数组
- 需指明元素类型和数组大小
- 语法:
elemenType arrayName[SIZE];
- 当一个数组被声明后,其元素的初值是任意的
- 数组大小必须是常量表达式
访问数组元素
- 数组下标是0基址的,即从
0
开始到arraySIZE-1
数组初始化语句
elementType arrayName[arraySIZE] = { value0, value1, value2,.....}
- 当使用数组初始化语句声明并创建一个数组时,C++允许省略数组大小,编译器会自动计算出数组大小
- C++允许只初始化数组的一部分元素
处理数组
- 通常需要for循环来处理数组元素
- 例子:
//假定数组定义如下:
const int ARRAY_SIZE = 10;
double myList[ARRAY_SIZE];
//下面是10个处理数组的例子
//用输入的值来初始化数组
cout << ("Enter " << ARRAY_SIZE << " value");
for (int i = 0; i < ARRAY_SIZE; i++)
{
cin >> myList[i];
}
//用随机数初始化数组
for (int i = 0; i < ARRAY_SIZE; i++)
{
myList[i] = rand() % 100;
}
//输出数组
for (int i = 0; i < ARRAY_SIZE; i++)
{
cout << myList[i];
}
//复制数组
for (int i = 0; i < ARRAY_SIZE; i++)
{
list[i] = myList[i];
}
//求所有数组的和
double total = 0;
for (int i = 0; i < ARRAY_SIZE; i++)
{
total + = myList[i];
}
//求最大元素
double max = myList[0];
for (int i = 0; i < ARRAY_SIZE; i++)
{
if (myList[i] > max)
{
max = myList[i];
}
}
//求最大元素最小下标
double max = myList[0];
int indexOfMax = 0;
for (int i = 0; i < ARRAY_SIZE; i++)
{
if (myList[i] > max)
{
max = myList[i];
indexOfMax = i;
}
}
//随机重排
srand(time(0));
for (int i = ARRAY_SIZE - 1; i > 0; i--)
{
int j = rand() % (i + 1);
double temp = myList[i];
myList[i] = myList[j];
myList[j] = temp;
}
//移动元素
double temp = myList[0];
for (int i = 0; i < ARRAY_SIZE; i++)
{
myList[i - 1] = myList[i];
}
myList[i - 1] = temp;
- 由于C++不检查数组边界,所以应该对此加以特别注意,以确保下标在合法范围内
//随机从一副纸牌的52中选出4张
#include <iostream>
#include <ctime>
#include <string>
using namespace std;
int main()
{
const int NUMBER_OF_CARDS = 52; //总牌数
//const int SELECT = 4; //需要选出的牌数
int deck[NUMBER_OF_CARDS];
string suits[] = {"Spades", "Hearts", "Diamonds", "Clubs"}; //牌色
string ranks[] = {"ACE", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"};
for (int i = 0; i < NUMBER_OF_CARDS; i++)
{
deck[i] = i;
}
srand(time(0));
for (int i = 0; i < NUMBER_OF_CARDS; i++) //随机抽牌
{
int index = rand() % NUMBER_OF_CARDS;
int temp = deck[i];
deck[i] = deck[index];
deck[index] = temp;
}
for (int i = 0; i < 4; i++)
{
string suit = suits[deck[i] / 13];
string rank = suits[deck[i] % 13];
cout << "Card number: " << deck[i] << " : " << rank << " of " << suit << endl;
}
return 0;
}
数组作为函数参数
- 当一个数组参数参数传递给了一个函数,数组的起始地址被传递给了函数中的数组参数,实际参数和形式参数使用的是同一个数组
//如何声明并调用数组传递给函数
#include <iostream>
using namespace std;
void printArray(int list[], int arraySize);
int main()
{
int numbers[5] = {1, 4, 3, 6, 8};
printArray(numbers, 5);
return 0;
}
void printArray(int list[], int arraySize)
{
for (int i = 0; i < arraySize; i++)
{
cout << list[i] << " ";
}
}
- 函数原型中的参数可以省略,例如:
void printArray(int [ ], int );
- 通常,想一个函数传递一个数组时,应该通过另一个参数将其大小也传递给函数
- C++使用值传递来给函数传递数组参数,向函数传递基本数据类型变量和传递数组,这两者有着重要的不同:
- 传递一个基本数据类型变量,意味着变量的值被传递给形参
- 传递一个数组意味着数组的起始地址被传递给形参,这个只被传递给函数中的数组参数,语义上讲,这就属于传递共享,也就是,函数中的数组和传递给函数的数组是同一个。因此,如果改变函数中的数组,将会改变函数之外的数组
防止函数修改传递参数的数组
- 可以在函数中定义const数组来防止数组在函数中被修改
数组作为函数值返回
- 可以向函数传递连个数组
//输出已有数组的逆序
#include <iostream>
using namespace std;
void reverse(const int list[], int newList[], int size)
{
for (int i = 0, j = size - 1; i < size; i++, j--)
{
newList[j] = list[i];
}
}
void printArray(const int list[], int size)
{
for (int i = 0; i < size; i++)
cout << list[i] << endl;
}
int main()
{
const int SIZE = 6;
int list[] = {1, 2, 3, 4, 5, 6};
int newList[SIZE];
reverse(list, newList, SIZE);
cout << "The origina array: ";
printArray(list, SIZE);
cout << endl;
cout << "The new array: ";
printArray(newList, SIZE);
cout << endl;
return 0;
}
//计算每个字符的出现次数
#include <iostream>
#include <ctime>
using namespace std;
const int NUMBER_OF_LETTERS = 26;
const int NUMBER_OF_RANDOM_LETTERS = 100;
void createArray(char[]);
void displayArray(const char[]);
void countLetters(const char[], int[]);
void displayCounts(const int[]);
int main()
{
char chars[NUMBER_OF_RANDOM_LETTERS];
createArray(chars);
cout << "The lowercase letters are :" << endl;
displayArray(chars);
int counts[NUMBER_OF_RANDOM_LETTERS];
countLetters(chars, counts);
cout << "\nThe occurrences of each letter are : " << endl;
displayCounts(counts);
return 0;
}
void createArray(char chars[])
{
srand(time(0));
for (int i = 0; i < NUMBER_OF_RANDOM_LETTERS; i++)
{
chars[i] = static_cast<char>('a' + rand() % ('z' - 'a' + 1));
}
}
void displayArray(const char chars[])
{
for (int i = 0; i < NUMBER_OF_RANDOM_LETTERS; i++)
{
if ((i + 1) % 20 == 0)
cout << chars[i] << " " << endl;
else
cout << chars[i] << " ";
}
}
void countLetters(const char chars[], int counts[])
{
for (int i = 0; i < NUMBER_OF_LETTERS; i++)
{
counts[i] = 0;
}
for (int i = 0; i < NUMBER_OF_RANDOM_LETTERS; i++)
{
counts[chars[i] - 'a']++;
}
}
void displayCounts(const int counts[])
{
for (int i = 0; i < NUMBER_OF_LETTERS; i++)
{
if ((i + 1) % 10 == 0)
cout << counts[i] << " " << static_cast<char>(i + 'a') << endl;
else
cout << counts[i] << " " << static_cast<char>(i + 'a') << " ";
}
}
搜索数组
- 如果一个数值已被排序,要找到一个数组元素,二分搜索法比顺序搜索法更有效
顺序搜索法
int linearSearch(const int list[], int key, int arraySize[])
{
for(int i = 0; i < arraySize; i++)
{
if(key == list[i])
return i;
}
return -1;
}
二分搜索方法
- 要求数组中的元素必须是有序存放的
int binarySearch(const int list[], int key, int listSize)
{
int low = 0;
int high = listSize - 1;
while(low < = high)
{
int mid = (low + high) / 2;
if(key < list[mid])
high = mid - 1;
else if(key == list[mid] )
return mid;
else
low = mid + 1;
}
return -low - 1; //不仅可以说明关键字不在列表中,还说明了关键字应该被插入在哪里
}
排序数组
选择排序
- 选择排序反复地选择最小元素,并将其与剩余列表开头元素交换
// 选择排序
void selectionSort(double list[], int listSize)
{
for (int i = 0; i < listSize; i++)
{
double currentMin = list[i];
int currentMinIndex = i;
for (int j = i + 1; j < listSize; j++)
{
if(currentMin > list[j])
{
currentMin = list[j];
currentMinIndex = j;
}
}
if(currentMin != i)
{
list[currentMinIndex] = list[i];
list[i] = currentMin;
}
}
}
C字符串
- C字符串是一个字符数组,以
'\0'(空终极符)
结尾 - 每一个字符串值都是一个C字符串
输入和输出字符串
- 输出:
cout<<s;
- 从键盘读取:
char city[7];
cout<<"Enter a city: ";
cin>>city;
cout<<"You enered "<<city<<endl;
- 读取带空格的字符串:
cin.getline(char array[ ], int size, char delimitChar);
C字符串函数