当前位置: 首页 > news >正文

网站建设开发环境自学服装设计下载

网站建设开发环境,自学服装设计下载,搜索引擎优化什么意思,电子商务型网站文章目录 前言一、C命名空间1、命名空间2、命名空间定义 二、第一个c程序1、c的hello world2、std命名空间的使用惯例 三、C输入输出1、c输入输出 四、c中缺省参数1、缺省参数概念2、缺省参数分类3、缺省参数应用 五、c中函数重载1、函数重载概念2、函数重载应用 六、… 文章目录 前言一、C命名空间1、命名空间2、命名空间定义 二、第一个c程序1、c的hello world2、std命名空间的使用惯例 三、C输入输出1、c输入输出 四、c中缺省参数1、缺省参数概念2、缺省参数分类3、缺省参数应用 五、c中函数重载1、函数重载概念2、函数重载应用 六、c中的引用1、 引用概念2、引用特性3、引用的应用 -- 做参数4、引用的应用 -- 做返回值 前言 C语言是结构化和模块化的语言适合处理较小规模的程序。对于复杂的问题规模较大的程序需要高度的抽象和建模时C语言则不合适。为了解决软件危机 20世纪80年代 计算机界提出了OOP(object oriented programming面向对象)思想支持面向对象的程序设计语言应运而生。 1982年Bjarne Stroustrup博士在C语言的基础上引入并扩充了面向对象的概念发明了一种新的程序语言。为了表达该语言与C语言的渊源关系命名为C。因此C是基于C语言而产生的它既可以进行C语言的过程化程序设计又可以进行以抽象数据类型为特点的基于对象的程序设计还可以进行面向对象的程序设计。 一、C命名空间 1、命名空间 在C/C中变量、函数和后面要学到的类都是大量存在的这些变量、函数和类的名称将都存在于全局作用域中可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化以避免命名冲突或名字污染namespace关键字的出现就是针对这种问题的。 例如在如下代码中会报出rand重定义的错误因为rand在stdlib库中为函数名。 #includestdio.h #includestdlib.hint rand 10; int main() {//因为stdlib库中定义了rand()函数所以全局定义的rand会和库中的rand产生命名冲突//在c语言中没办法解决类似这样的命名冲突的问题所以c提出了namespace来解决printf(%d\n, rand);return 0; }c的namespace就可以解决c语言中的命名冲突问题。 #includestdio.h #includestdlib.h//命名空间域 namespace dong {int rand 0; }int main() {printf(%d\n, rand); //此时rand为stdlib内的函数// ::为域作用限定符printf(%d\n, dong::rand); //此时dong::rand为dong命名空间域里面的rand变量return 0; }2、命名空间定义 定义命名空间需要使用到namespace关键字后面跟命名空间的名字然后接一对{}即可{}中即为命名空间的成员。 #includestdio.h #includestdlib.h//命名空间域 namespace dong {//命名空间中定义变量int rand 0;//命名空间还可以嵌套定义//嵌套定义命名空间namespace inside{int tmp 5;struct Stu{char name[20];int age;};}//命名空间中定义函数void func(){printf(func()\n);}//命名空间中定义结构体struct TreeNode{struct TreeNode* left;struct TreeNode* right;int val;}; }int main() {printf(%d\n, rand); //此时rand为stdlib内的函数// ::为域作用限定符printf(%d\n, dong::rand); //此时dong::rand为dong命名空间域里面的rand变量//此时会去全局域找func()函数如果全局域没有定义func()就会报错//func(); //dong::指定了去命名空间域dong里面找func()的定义。dong::func(); //dong::指定了去命名空间域dong里面找struct TreeNode的定义。struct dong::TreeNode node;//访问嵌套定义的命名空间里面的变量printf(%d\n, dong::inside::tmp);struct dong::inside::Stu stu;return 0; }当我们在一个项目中如果有多个模块都用到了类似栈和队列的操作并且它们也定义了Stack和QueueNode结构等此时我们可以直接使用一个namespace dong的命名空间将该模块的.h和.c文件都包含在namespace dong命名空间域中此时在namespace dong里面的变量和结构体定义就不会和别的模块里面的变量和结构体产生冲突了。 此时当我们想使用命名空间dong中定义的结构体和方法时就不能再想下面图片中那样定义了。因为一个命名空间就定义了一个新的作用域命名空间中的所有内容都局限于该命名空间中 此时使用dong命名空间的结构体和函数就可以如下图一样的形式使用。这样就可以避免每个模块之间命名冲突比如这个模块使用这些操作的话就去dong命名空间中去找这些定义这个模块再使用其他操作的话可以去另一个命名空间中去找这些定义这两个命名空间中可以定义相同名字的结构体或变量或函数只要在使用时标明去哪个命名空间去找这些结构体或变量或函数的定义即可。 二、第一个c程序 1、c的hello world 下面为c语言写的第一个hello world程序。 #includeiostream using namespace std; int main() {cout hello world endl;return 0; }其中该语句说明引入了c里面的io流的库。 #includeiostream该语句说明将std命名空间里面的成员都引入c中标准库的东西都放到了std中即如果有了该语句在下面的代码中使用std里面的变量时就不需要写成std::cout而是可以直接写成cout省略前面的std::。因为此时std命名空间的成员已经都引入到全局域了所以编译器可以在全局域里面找到这些成员的定义。 using namespace std; 如果我们将using namespace std;注释掉的话再使用命名空间std里面的成员时就需要像下面这样写。 #includeiostream //using namespace std; int main() {std::cout hello world std::endl;return 0; }我们还可以只引入std库里面部分的变量名称。 #includeiostream //using namespace std; //只引入我们需要的成员即可 using std::cout; using std::cin; using std::endl; int main() {cout hello world endl;return 0; }2、std命名空间的使用惯例 1.在日常练习中建议直接using namespace std即可这样就很方便。 2 using namespace std展开标准库就全部暴露出来了如果我们定义跟库重名的类型/对象/函数就存在冲突问题。该问题在日常练习中很少出现但是项目开发中代码较多、规模大就很容易出现。所以建议在项目开发中使用像std::cout这样使用时指定命名空间 或 using std::cout展开常用的库对象/类型等方式。 #includeiostream #includevector //引入常用的库对象/类型 using std::cout; using std::endl; int main() {//指定命名空间访问std::vectorint v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);cout hello world! endl;cout hello world! endl;cout hello world! endl;cout hello world! endl;return 0; }三、C输入输出 1、c输入输出 1.使用cout标准输出对象(控制台)和cin标准输入对象(键盘)时必须包含 iostream 头文件以及按命名空间使用方法使用std。 2. cout和cin是全局的流对象endl是特殊的C符号表示换行输出他们都包含在包含 iostream 头文件中。 3. 是流插入运算符 是流提取运算符。 4. 使用C输入输出更方便不需要像printf/scanf输入输出时那样需要手动控制格式。C的输入输出可以自动识别变量类型。 在c语言中当我们需要在标准输出流stdout中打印数据时使用printf函数当我们要读取数据时需要使用scanf从标准输入流stdin中获取数据并且这两个函数在打印和获取数据时都要标明数据的类型。 但是c中不需要像c语言那样标明数据类型。 #includeiostream //using namespace std; int main() {// 是流插入运算符std::cout hello world std::endl;//std命名空间中的endl就类似于换行符即 std::endl 等价于 \nstd::cout hello world \n;//c中自动识别类型int i 11;double d 11.11;printf(%d %lf\n, i, d);//c中可以自动识别类型std::cout i , d std::endl;//c语言中读取数据scanf(%d %lf, i, d);printf(%d,%lf\n, i, d);//c中读取数据// 为流提取std::cin i d;std::cout i , d std::endl;//当需要精度控制时因为c实现精度控制比较麻烦所以还可以使用c语言的printf()printf(%.2lf\n, d);return 0; }四、c中缺省参数 1、缺省参数概念 缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时如果没有指定实参则采用该形参的缺省值否则使用指定的实参。缺省值必须是常量或者全局变量。 //缺省参数 #includeiostream using namespace std; void Func(int a 0) {cout a endl; } int main() {//当调用函数Func()时传递的有实参则缺省参数的值不起作用Func(1);Func(2);Func(3);//当调用函数Func()时没有传递实参此时缺省参数的值就起作用Func();return 0; }2、缺省参数分类 全缺省参数全缺省参数需要注意的就是在函数调用时不能直接跳过前面的形参然后传值给后面的形参。 //全缺省参数 #includeiostream using namespace std; void TestFunc(int a 10, int b 20, int c 30) {cout a a endl;cout b b endl;cout c c endl endl; } int main() {TestFunc();//传入的实参是按照从左向右的顺序赋值的只有一个实参就赋给形参aTestFunc(1);//有两个实参就赋给a和bTestFunc(1,2);//有三个实参就赋给a、b、cTestFunc(1,2,3);//这里需要注意的是不能直接跳过前面的a然后直接传值给b//TestFunc(, 1, ); //这样是错误的语法不允许return 0; }半缺省参数这里需要注意的是半缺省参数必须从右往左依次来给出不能间隔着给。 //半缺省参数 #includeiostream using namespace std;//这里函数TestFunc只定义了两个缺省参数所以在调用时必须要将形参a的值通过实参传递过来 //半缺省参数必须从右往左依次来给出不能间隔着给 // void TestFunc(int a 10, int b, int c 30) //这样定义的就是错误的 void TestFunc(int a, int b 20, int c 30) {cout a a endl;cout b b endl;cout c c endl endl; } int main() {//此时必须要将形参a的值通过实参传递过去//TestFunc(); //错误// //传入的实参是按照从左向右的顺序赋值的只有一个实参就赋给形参aTestFunc(1);//有两个实参就赋给a和bTestFunc(1, 2);//有三个实参就赋给a、b、cTestFunc(1, 2, 3);return 0; }3、缺省参数应用 前面我们使用c语言实现了栈的创建和初始化当我们初始化栈时会为栈的容量开辟4个空间但是当我们知道需要向栈中插入多少数据时此时如果还每次只开辟capacity*2的空间然后一次一次开辟到我们需要的空间时这样程序的开销就大了因为每次开辟空间还有可能需要将数据转移。而此时缺省参数就可以解决上面的问题我们将栈容量定义为缺省参数当在初始化栈时如果已经提前知道了需要多少空间我们就可以给capacity传入值而当不知道需要多少空间时就可以不用给capacity传值此时capacity就为4。 #includeiostream #includestdlib.h struct Stack {int* a;int top;int capacity; }; //将栈的容量capacity设为缺省参数 void StackInit(struct Stack* ps, int capacity 4) {//当调用StackInit()没有给capacity传参时缺省参数的值就起作用此时capacity为4//当调用StackInit()给capacity传参时,此时缺省参数的值就不起作用capacity的值就为传进来的值ps-a (int*)malloc(sizeof(int) * capacity);//ps-top 0;ps-capacity capacity;}int main() {//当我们在使用栈时已经提前知道了一定会插入100个数据所以可以直接将capacity的值当作实参传入//这样可以提前开好空间插入数据时就避免了扩容程序开销就会小一些struct Stack st1;StackInit(st1, 100);//当我们不知道需要插入多少数据时就可以不传入capacity的值。struct Stack st2;StackInit(st2); } 上面的代码中我们是直接将StackInit(struct Stack* ps,int capacity4)函数写出来了而在项目中我们需要在.h文件中先将StackInit(struct Stack* ps,int capacity4)声明一下然后在.c文件中完成StackInit(struct Stack* ps,int capacity4)函数的定义。此时就会产生一个问题如果StackInit()函数的声明和定义中给缺省参数capacity的值不一样时那么编译器会以哪个为准呢所以缺省参数不能在函数声明和定义中同时出现。 此时编译器就不知道该以哪一个为准了。 所以都是在函数声明中给缺省参数值然后函数定义时就不需要给缺省参数值了。 那如果在函数定义时给了缺省参数而在函数声明时没有给缺省参数那么此时缺省参数的值不会起作用。因为已经在函数声明时说明了该函数没有缺省参数但是调用时按缺省参数的形式调用就会出现错误。 五、c中函数重载 1、函数重载概念 函数重载是函数的一种特殊情况C允许在同一作用域中声明几个功能类似的同名函数这些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同常用来处理实现功能类似数据类型不同的问题。 函数重载 – 参数个数不同 //函数重载 参数个数不同 #includeiostream using namespace std; int Add(int a, int b, int c) {return a b c; } int Add(int a, int b) {return a b; }int main() {cout Add(2, 2, 2) endl;cout Add(2, 2) endl;return 0; }函数重载 – 参数类型不同 //函数重载 参数类型不同 #includeiostream using namespace std; int Add(int a, int b) {return a b; } double Add(double a, double b) {return a b; }int main() {cout Add(2, 2) endl;cout Add(1.1, 2.2) endl;return 0; }函数重载 – 参数类型顺序不同 //函数重载 参数类型顺序不同 #includeiostream using namespace std; void func(int i, char ch) {cout void func(int i, char ch) endl; } void func(char ch, int i) {cout void func(char ch, int i) endl; } int main() {func(1, a);func(a, 1);return 0; }当函数返回值不同时不构成函数重载只有参数不同才构成重载。因为函数返回值不同函数调用时编译器无法区分去调用哪一个函数。 2、函数重载应用 在c语言中当我们要交换两个int型变量的值时需要写一个函数当我们要交换两个double类型的值时又要写一个函数而且两个函数的名字还不能相同。 #includestdio.h void Swapi(int* p1, int* p2) {int tmp *p1;*p1 *p2;*p2 tmp; }void Swapd(double* p1, double* p2) {double tmp *p1;*p1 *p2;*p2 tmp; }int main() {int a 1;int b 2;double c 1.1;double d 2.2;Swapi(a, b);Swapd(c, d);printf(%d %d\n, a, b);printf(%lf %lf\n, c, d);return 0; }但是c中的函数重载就可以解决这个问题只要两个名称相同的函数的参数数量、类型或顺序不同就可以构成函数重载。 #includeiostream using namespace std; void Swap(int* p1, int* p2) {int tmp *p1;*p1 *p2;*p2 tmp; }void Swap(double* p1, double* p2) {double tmp *p1;*p1 *p2;*p2 tmp; }int main() {int a 1;int b 2;double c 1.1;double d 2.2;Swap(a, b);Swap(c, d);cout a b endl;cout c d endl;return 0; }通过上述代码我们可以发现c中的cout和cin可以自动识别类型其实也是用到了函数重载这样cout和cin才可以在各种类型时都可以用。 六、c中的引用 1、 引用概念 引用不是新定义一个变量而是给已存在变量取了一个别名编译器不会为引用变量开辟内存空间它和它引用的变量共用同一块内存空间。 引用变量的定义 类型 引用变量名(对象名) 引用实体 //引用 #includeiostream using namespace std;int main() {int a 0;//b为a变量的别名a和b共用一块内存空间不管修改a或b的值这片空间的值都会改变int b a;//a和b共用一块内存空间所以a和b的地址一样cout b endl;cout a endl;a;b;cout a endl;cout b endl;return 0; }2、引用特性 1.引用在定义时必须初始化。 2.一个变量可以有多个引用。 3.引用一旦引用一个实体再不能引用其他实体。 //引用特性 #includeiostream using namespace std;int main() {int a 1;//1.引用在定义时必须初始化不然就不知道该引用是哪个变量的别名//int b; //2.一个变量可以有多个引用即这些变量都和a共享一片内存空间只要其中一个引用的值改变了该内存空间的值就改变了int b a;int c a;//还可以给a的别名c再起一个别名此时d也和c一样与a共享一片内存空间。int d c;a;b;c;d;cout a endl;cout b endl;cout c endl;cout d endl;int x 10;//3.引用一旦引用一个实体就不能再引用其他实体b x; //因为此时是给b赋值为x并不是将b变为x的别名cout a endl;cout b endl;cout c endl;cout d endl;return 0; }常引用 //常引用 #includeiostream using namespace std; int main() {const int a 10;//下列语句编译时会出错因为a被const修饰a为常变量//int ra a; //而将ra用const修饰就不会出错const int ra a;//下列语句编译时会出错因为b为常量//int b 10;const int b 10;double d 12.34;//下列语句编译时会出错因为类型不同//int rd d; const int rd d;return 0; }3、引用的应用 – 做参数 (1)输出型参数 引用的一个使用场景就是作为输出型参数即在函数定义形参时将形参定义为实参的引用然后就可以通过引用来改变实参的值。 //引用应用 #includeiostream using namespace std; //形参是实参的别名即引用所以可以通过形参来改变实参的值 void Swap(int r1, int r2) {int tmp r1;r1 r2;r2 tmp; } int main() {int a 0;int b 2;cout a a endl;cout b b endl;Swap(a, b);cout a a endl;cout b b endl;return 0; }所以我们可以使用引用来修改一下之前写的顺序表我们还记得之前写的顺序表代码如下。 typedef int SLDataType; typedef struct SeqList {SLDataType* data; //指向动态开辟的数组int size; //有效数据个数int capacity; //顺序表的容量 }SL;void SLInit(SL* ps) {assert(ps);SLDataType* tmp (SLDataType*)calloc(4, sizeof(SLDataType)); //初始化时自动开辟4个空间if (tmp NULL){perror(SLInit);exit(-1); //退出程序}ps-data tmp;ps-size 0;ps-capacity 4; }int main() {//创建一个SL类型的结构体变量SL s;//需要将s地址传入函数这样函数中才能通过s的地址来改变s结构体变量的值SLInit(s);return 0; }当我们了解了引用之后我们就可以将上面的代码改为使用引用来写而不需要使用指针。 #includeiostream #includestdlib.h #includeassert.h using namespace std;typedef int SLDataType; typedef struct SeqList {SLDataType* data; //指向动态开辟的数组int size; //有效数据个数int capacity; //顺序表的容量 }SL;//形参是实参的别名即引用所以可以通过形参来改变实参的内容。 void SLInit(SL ps) {assert(ps);SLDataType* tmp (SLDataType*)calloc(4, sizeof(SLDataType)); //初始化时自动开辟4个空间if (tmp NULL){perror(SLInit);exit(-1); //退出程序}ps.data tmp;ps.size 0;ps.capacity 4; }int main() {//创建一个SL类型的结构体变量SL s;//此时直接将该变量传入函数中SLInit(s);return 0; }那么我们前面写的单链表也可以改成使用引用的版本我们之前写的单链表代码如下。在实现单链表的一些操作时我们使用到了二级指针。 #includestdlib.h #includeassert.h #includestdio.htypedef int SLTDataType; typedef struct SListNode {SLTDataType data;struct SListNode* next; }SLTNode;void SListPushBack(SLTNode** pphead, SLTDataType x) {assert(pphead);SLTNode* newNode (SLTNode*)malloc(sizeof(SLTNode)); //创建一个新结点assert(newNode);newNode-data x;newNode-next NULL;if (*pphead NULL) //如果单链表为空就使新结点为单链表的首结点。{*pphead newNode;}else{//找单链表的尾结点SLTNode* tail *pphead;while (tail-next ! NULL){tail tail-next;}tail-next newNode;} }int main() {//创建一个单链表结点指针并将该指针赋值为NULL代表该单链表为空SLTNode* s NULL;//此时如果函数SListPushBack()中想要改变s的值不为NULL就需要将s的地址传入函数中//而s本来就为指针所以SListPushBack()函数的形参要定义一个二级指针用来接收指针s的地址。SListPushBack(s, 1);SListPushBack(s, 2);SListPushBack(s, 3);SListPushBack(s, 4);return 0; }现在我们可以使用引用来改变上面的代码这样我们就不用使用二级指针了。 #includestdlib.h #includeassert.h #includestdio.htypedef int SLTDataType; typedef struct SListNode {SLTDataType data;struct SListNode* next; }SLTNode;//将函数的形参定义为一个SLTNode*类型的指针变量的引用 //此时pphead就是list的别名phead的改变也会影响list void SListPushBack(SLTNode* pphead, SLTDataType x) {assert(pphead);SLTNode* newNode (SLTNode*)malloc(sizeof(SLTNode)); //创建一个新结点assert(newNode);newNode-data x;newNode-next NULL;if (pphead NULL) //如果单链表为空就使新结点为单链表的首结点。{pphead newNode;}else{//找单链表的尾结点SLTNode* tail pphead;while (tail-next ! NULL){tail tail-next;}tail-next newNode;} }int main() {//创建一个单链表结点指针即代表该单链表为空SLTNode* list NULL;//此时SListPushBack(SLTNode* pphead, SLTDataType x)的形参为list指针变量的引用//所以在函数中通过该引用就可以改变list的内容SListPushBack(list, 1);SListPushBack(list, 2);SListPushBack(list, 3);SListPushBack(list, 4);return 0; }在一些数据结构的书上也会这样定义即将上面的代码再次简化。 #includestdlib.h #includeassert.h #includestdio.htypedef int SLTDataType; typedef struct SListNode {SLTDataType data;struct SListNode* next; }SLTNode,*PSLTNode;//*PSLTNode等价于下面的语句 //typedef struct SListNode* PSLTNode;//将函数的形参定义为一个SLTNode*类型的指针变量的引用 //void SListPushBack(SLTNode* pphead, SLTDataType x) //上面的语句等价于下面的语句 void SListPushBack(PSLTNode pphead, SLTDataType x) {assert(pphead);SLTNode* newNode (SLTNode*)malloc(sizeof(SLTNode)); //创建一个新结点assert(newNode);newNode-data x;newNode-next NULL;if (pphead NULL) //如果单链表为空就使新结点为单链表的首结点。{pphead newNode;}else{//找单链表的尾结点SLTNode* tail pphead;while (tail-next ! NULL){tail tail-next;}tail-next newNode;} }int main() {//等价于SLTNode* s;//通过PSLTNode创建一个单链表结点指针该指针为空就说明该单链表为空PSLTNode s NULL;SListPushBack(s, 1);SListPushBack(s, 2);SListPushBack(s, 3);SListPushBack(s, 4);return 0; }(2)大对象传参提高效率 #includetime.h #includeiostream using namespace std; struct A {int a[10000]; };void TestFunc1(A aa) {}void TestFunc2(A aa) {}int main() {A a;//以值作为函数参数int begin1 clock();for (int i 0; i 10000; i){//每次调用TestFunc1函数都会在该函数中重新创建一个A结构体并且该结构体的数据都拷贝实参a的值TestFunc1(a);}int end1 clock();//以引用作为函数参数int begin2 clock();for (int i 0; i 10000; i){//调用函数TestFunc2不会重新创建A结构体所以该循环会效率更高TestFunc2(a);}int end2 clock();cout end1 - begin1 endl;cout end2 - begin2 endl;return 0; }4、引用的应用 – 做返回值 (1)输出型返回对象 我们知道c语言中每当有一个函数调用时编译器都会在栈区中为该次函数调用开辟一片空间例如有如下一个程序。Count()函数的返回值为int型那么函数调用时是如何将返回值带回到main函数内的呢 我们先看下面两个传值返回的例子。 (1)我们可以看到当Count函数执行完后编译器为该函数分配的空间就会回收此时存储返回值n的空间也销毁那么正确的n的值是怎么回到main函数中的呢其实当Count函数返回值较小时此时系统会直接将Count函数的返回值存在寄存器中然后main函数去该寄存器取返回值即可。当Count函数返回值较大时会先在main的栈帧中创建一个临时变量然后将Count栈帧里面的n拷贝到main的临时变量中不会直接取Count函数的栈帧中取n因为此时Count函数的栈帧已经销毁n的内存空间中已经存的不是原来的值了。 (2)下图中的n为static修饰的静态变量所以此时n存储在静态区。此时虽然函数Count的空间销毁后n还是存在静态区中没有被销毁但是在main函数中获取Count函数的返回值时也不会去静态区去取n的值。因为编译器不知道此时静态区中有Count函数的返回值。而是还会将Count的返回值和上面例子的处理情况一样即将Count函数的返回值拷贝一份到main函数的临时变量中。 所以不管n是在栈区还是静态区编译器都会生成一个函数返回对象的拷贝用来作为函数调用返回值这样调用函数的栈帧销毁了返回值也还有拷贝的一份不会让函数的返回值丢失。 我们再看下面的两个传引用返回的例子。 下面的例子中main函数中的ret的值是不确定的所以这种情况不能使用传引用返回。只能使用传值返回。 下面的例子中就可以使用传引用返回因为返回值n在静态区中Count函数执行时的空间被系统销毁后n的值还在。所以当出了函数作用域返回对象就销毁了时那么一定不能用传引用返回一定要用传值返回只有在出了函数作用域后返回对象还没有销毁的情况时才可以使用传引用返回。而传值返回不管什么情况都可以使用因为传值返回会将返回值拷贝一份。传引用返回就是比传值返回少了一次返回值的拷贝。 知道了上面的知识后我们又可以将以前写的关于顺序表的修改数据的函数改一下改为传引用返回的函数。原来我们写的顺序表的修改数据的代码如下。 #includeassert.h #includestdlib.h #includestdio.h typedef int SLDataType; typedef struct SeqList {SLDataType* data; //指向动态开辟的数组。int size; //有效数据的个数int capacity; // 容量空间的大小 }SL; void SLInit(SL* ps) {assert(ps);SLDataType* tmp (SLDataType*)calloc(4, sizeof(SLDataType)); //初始化时自动开辟4个空间if (tmp NULL){perror(SLInit);exit(-1); //退出程序}ps-data tmp;ps-size 0;ps-capacity 4; }void SLCheckCapacity(SL* ps) {assert(ps);if (ps-size ps-capacity ps-size ! 0){SLDataType* tmp (SLDataType*)realloc(ps-data, (2 * ps-capacity) * sizeof(SLDataType));if (tmp NULL){perror(SLCheckCapacity);exit(-1);}ps-data tmp;ps-capacity ps-capacity * 2;} }void SLPushBack(SL* ps, SLDataType x) {assert(ps);SLCheckCapacity(ps); //先检查是否需要扩容ps-data[ps-size] x; //插入数据ps-size; }void SLModify(SL* ps, int pos, SLDataType x) {assert(ps pos 0 pos ps-size);ps-data[pos] x; }int main() {SL s;SLInit(s);SLPushBack(s, 1);SLPushBack(s, 2);SLPushBack(s, 3);SLPushBack(s, 4);SLModify(s, 2, 6);return 0; }然后我们可以将SLModify函数改为一个传引用返回的函数这样我们就可以根据返回的别名来修改顺序表中元素的值。 #includeassert.h #includestdlib.h #includestdio.h #includeiostream using namespace std; typedef int SLDataType; typedef struct SeqList {SLDataType* data; //指向动态开辟的数组。int size; //有效数据的个数int capacity; // 容量空间的大小 }SL; void SLInit(SL ps) {assert(ps);SLDataType* tmp (SLDataType*)calloc(4, sizeof(SLDataType)); //初始化时自动开辟4个空间if (tmp NULL){perror(SLInit);exit(-1); //退出程序}ps.data tmp;ps.size 0;ps.capacity 4; }void SLCheckCapacity(SL ps) {assert(ps);if (ps.size ps.capacity ps.size ! 0){SLDataType* tmp (SLDataType*)realloc(ps.data, (2 * ps.capacity) * sizeof(SLDataType));if (tmp NULL){perror(SLCheckCapacity);exit(-1);}ps.data tmp;ps.capacity ps.capacity * 2;} }void SLPushBack(SL ps, SLDataType x) {assert(ps);SLCheckCapacity(ps); //先检查是否需要扩容ps.data[ps.size] x; //插入数据ps.size; }int SLModify(SL ps, int pos) {assert(ps pos 0 pos ps.size);return ps.data[pos]; }int main() {SL s;SLInit(s);SLPushBack(s, 1);SLPushBack(s, 2);SLPushBack(s, 3);SLPushBack(s, 4);for (int i 0; i s.size; i){cout SLModify(s, i) ;}cout endl;//此时返回的就是s.data[2]的别名通过该别名就可以修改s.data[2]的值SLModify(s, 2);SLModify(s, 3) 10;for (int i 0; i s.size; i){cout SLModify(s, i) ;}cout endl;//虽然也可以直接s.data[2]来修改但是这个例子就是举例说明一下传引用返回的应用s.data[2];for (int i 0; i s.size; i){cout SLModify(s, i) ;}cout endl;return 0; }
http://www.pierceye.com/news/908069/

相关文章:

  • .耐思尼克官方网站工程公司会计账务处理
  • 如何进入微网站毕业设计网站开发
  • 已经备案的网站新增ip怎么做网站分站如何做
  • 网站建设 常州怎么做网络推广营销
  • 海南建设工程信息网站常用网站建设软件
  • 福州网络推广建站网站建设工作室深圳
  • html的网站案例长春头条新闻今天
  • 免费的十大免费货源网站产品设计开发流程图
  • 做网站的内容网站建设工作室有几个部门
  • jquery win8风格企业网站模板wordpress编辑器 模板
  • 北京国互网网站建设电话免费网站怎么盈利模式
  • 网站建设图片如何加载ssh做电商 网站
  • 网站开发资质网站域名服务错误
  • html5 社团网站模板 代码下载上海做营销网站哪个公司好
  • 动易网站 模板南京企业建站系统模板
  • 网站实名网站建设技术百科
  • 网站策划书范文模板网盟推广费
  • 先做网站还是先做app唐山模板建站定制网站
  • 小城镇建设的网站中的主要观点廊坊网站设计公司
  • 银联支付网站建设企业qq登录
  • dw怎样做网站链接aspcms建站
  • 网站的栏目wordpress php版本太低
  • 浙江网站制作出效果图
  • 电子商务是电商吗产品seo是什么意思
  • 黑龙江省建设工程质量协会网站中文搜索引擎网站
  • 汽车报价网站宁波网络推广丿易企网怎么样
  • php个人网站简洁手机下载视频网站模板
  • 双语网站方法wordpress分类内没有文章
  • 做网站后期为什么续费仿uehtml WordPress
  • 网站实时显示wordpress 网站