基本定义
数组
T[size]就是具有size个T类型元素的数组(类型)。
结构
数组是相同类型的元素的一个聚集。一个struct则是任意类型元素的一个聚集。struct address{
char* name;
char* street;
long zip;
};
结构对象常常通过指针用->运算符访问,如p->name 相当于(*p).name。
结构类型对象的大小未必是其成员的大小之和。
两个结构总是不同的类型,即使它们有相同的成员。
指针
T*就是到类型T的指针
对指针的操作就是间接引用,间接运算符也是*
int* pi;
char** ppc; //到字符的指针的指针
int* api[15]; //15个到int的指针的数组
int (*fp)(char*); //到函数的指针
int* f(char*); //返回int*的函数
常量
const实际上改变了类型,它限制了对象能够使用的方式。
引用
一个引用就是某对象的另一个名字。记法为X&表示到X的引用。
引用必须初始化。
引用最明显的实现方式是作为一个常量指针const*,每次使用的时候都间接访问。这样想象并没有问题,不过一个引用并不是一个对象,不能像指针那样操作。
const T&的初始值不一定是左值,也不一定是类型T的。(临时变量、强制转换)
以常量的引用作为函数参数是非常普遍的应用。
“特殊”指针:
字符串文字常量,如:"this is a example"其类型就是const char[18],最后一个字符是"\0"。
可以将字符串文字常量赋值给char*,不过不能通过指针进行修改。
空指针 0(尽量不要用NULL宏?或使用const int NULL=0;)。
void*:一个指向任何对象类型的指针都可以赋值给类型为void*的指针(反之则不然,必须显示转换)。最重要用途是需要向函数传递一个指针,而又不能对对象的类型做任何假设。还有就是从函数返回一个无类型的对象。要使用这样的对象,必须通过显示的类型转换。
复合情况
到数组的指针
int v[]={1,2,3,4,5,6};
int* p1=v;
int* p2=&v[0];
数组参数被隐式转换到指针后,这也意味着对被调用函数而言,数组的大小信息被丢失了。
常量指针
*const---》常量指针
const char* ccp; //到const char的指针
char const* ccp2; //到const char的指针
char*const cpc; //到char的const指针
--------------------------------------------------------------------------------------
习题:
1、写出如下声明
char* pc; //一个到字符的指针
int ia[10];//一个包含10个整数的数组
int (&ria)[10]=ia;//一个到包含10个整数的数组的引用
string (*ps)[10]//一个到字符串的数组的指针
char** ppc;//一个到字符的指针的指针
const int ci=100;//一个常量整数
const int *pci=PI; //一个到常量整数的指针,PI为const int
int const* cpi=itest;//一个到整数的常量指针
int *pi[15]; //15个到整数的指针的数组
3、用typedef去定义如下类型
typedef unsigned char uc;//unsigned char,
typedef const unsingned char cuc;//const unsigned char
typedef int* ptoi;//到整数的指针
typedef char** ptoptoc;//到字符的指针的指针
typedef char *((*ptoptoca)[10]);//到字符指针的数组的指针
typedef int *ptoi[7];//7个到整数的指针的数组
typedef int *((*ptoi)[7])//到包含7个整数的指针的数组的指针
typedef int *test[7][8]//包含8个数组的数组,其中每个数组包含7个到整数的指针
参见教你如何理解复杂的声明,到现在还有点而晕乎乎的,似懂非懂
5、下面例子中,数组str的大小是多少?
char str[]="a short string";
sizeof(str)=15; //包括一个'\0'
strlen(str)=14; //str的长度是多少?
6、如下哪些调用时合法的?哪些调用将导致编译器引进临时变量?
‘a’ | 49 | 3300 | c | uc | sc | |
f(char) | 合法 | 合法 | 非法 | 合法 | 合法? | 合法 |
g(char&) | 非法 | 非法 | 非法 | 合法 | 合法? | 合法 |
h(const char&) | 合法,引入临时变量 | 合法,引入临时变量 | 合法,引入临时变量 | 合法 | 合法 | 合法 |
unsigned char | signed char |
7、定义一个包含一年中各月份的名字和每个月的提案数的表格,分别用两个数组、结构实现。
#include<iostream>
using namespace std;
int main(){
char *Month[12]={"Jan","Feb","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"};
int days[12]={31,28,31,30,31,30,31,31,30,31,30,31};
struct sMonth{
char *mon;
int days;
};
sMonth test[12];
for(int i=0,i<12,i++){
test[i].mon=Month[i];
test[i].days=days[i];
}
for(int i=0,i<12,i++) cout<<Month[i]<<'\t';
cout<<endl;
for(int i=0,i<12,i++) cout<<Days[i]<<'\t';
cout<<endl;
for(int i=0,i<12,i++){
cout<<test[i].mon<<'\t'<<test[i].days<<endl; //数列
}
return 0;
}
9、找一个例子,其中将一个名字用于它自己的初始式是有意义的。
??不会
10、定义一个字符串的数组,其中的字符串保存的是月份的名字。将这些字符串传递给一个函数打印出来
#include<iostream>
#include<string>
using namespace std;
void printstring(string s[],int n){
for int(i=0,i<n,i++) cout<<s[i]<<endl;
}
int main(){
string month[12]={"JAN","FEB","MAR",…};
printstring(month,3);
return 0;
}
11、从输入读一系列单词,使用Quit作为输入的结束单词。按照读入顺序打印出(重复值不打印)。排序后再打印。
//采用了标准库<string>/<vector>,自己写感觉还有点儿费劲
#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
using namesapce std;
bool ifExist(vector<string> vs,string s){
if(vs.size==0) return false;
vector<string>::iterator it = find(vs.begin(), vs.end(), s);
if (it != vs.end())
return ture;
else
return false;
}
void print(vector<string> vs){
for(int i=0,i<vs.size,i++)
cout<<vs[i]<<'\t';
}
int main(){
vector<string> vstest;
string stest;
cout<<"Please input the words and ends with Quit!"<<endl;
cin>>stest;
while(stest!="Quit"){
if(!ifExist(vstest,stest)) vstest.push_back(stest); //重复的数值不放入vector中
cin>>stest;
}
print(vstest);
sort(vsteest.begin(),vstest.end()); //标准排序函数
print(vstest);
return 0;
}
12、写一个函数,它统计一个string中一对字母出现的次数。写另一个函数对char*做同样多的事情。
//C风格的字符串的程序未实现
//对于一对字母扩展为可变长度的字符串
#include<iostream>
#include<string>
using namespace std;
int sCount(const string &string1,const string &string2){
int icount=0;
int pos=0;
while((pos=string1.find(string2,pos))!=string::npos){
icount+=1;
cout<<"The position is at "<<pos<<endl;
pos+=string2.size();
}
return icount;
}
int main(){
string s1,s2;
cout<<"Please input the source string and the substring."<<endl;
cin>>s1>>s2;
cout<<scount(s1,s2);
return 0;
}
13、定义一个struct Date以保存日期的轨迹。提供一些函数,从输入读Date,向输出写Date,以及用一个日期去初始化Date。
//此处省略所有对时间合理性的判断
#include <iostream>
struct Date{
int year;
int month;
int day;
};
void inputdate(Date &test,int x,int t,int z){
test.year=x;
test.month=y;
test.day=z;
}
void outputdate(const Date &test){
cout<<test.year<<'\t'<<test.month<<'\t'<<test.day<<endl;
}
int main(){
Date today=(1895,4,17);//签订马关条约的日期
output(today);
return 0;
}