2026/1/10 6:42:45
网站建设
项目流程
中国做网站的公司,小城市网站建设业务,动漫视频网站html模板,网站开发命名规则C入门全面指南#xff1a;从基础到现代C特性
前言
C作为一种强大、高效且广泛应用的编程语言#xff0c;自1979年由Bjarne Stroustrup在贝尔实验室创建以来#xff0c;已经发展成为软件开发领域的重要基石。它既保留了C语言的高效性和底层控制能力#xff0c;又引入了面向…C入门全面指南从基础到现代C特性前言C作为一种强大、高效且广泛应用的编程语言自1979年由Bjarne Stroustrup在贝尔实验室创建以来已经发展成为软件开发领域的重要基石。它既保留了C语言的高效性和底层控制能力又引入了面向对象编程、泛型编程等现代编程范式。在当今的软件开发领域C广泛应用于操作系统、游戏开发、嵌入式系统、高性能计算、金融交易系统等对性能要求极高的领域。学习C不仅能够帮助我们理解计算机系统的底层原理还能培养严谨的编程思维和高效的问题解决能力。本指南将系统性地介绍C的核心特性从基础语法到现代C11标准的新特性通过丰富的代码示例和详细解释帮助读者建立坚实的C编程基础。一、C关键字C共有63个关键字这些关键字是语言的核心组成部分具有特殊含义不能作为标识符使用。下面按照功能分类详细介绍主要关键字1. 数据类型关键字// 基本类型bool,char,wchar_t,char16_t,char32_t,char8_t(C20)short,int,long,longlongfloat,double,longdoublevoid// 类型修饰符signed,unsignedconst,volatile,mutable2. 存储类关键字auto,register,static,extern,thread_local(C11)3. 控制流关键字// 条件控制if,else,switch,case,default// 循环控制for,while,do,break,continue// 跳转goto,return4. 面向对象编程关键字class,struct,union,enum,enumclass(C11)public,protected,privatevirtual,override(C11),final(C11)this,friend,explicit5. 模板编程关键字template,typename,class(在模板中)6. 异常处理关键字try,catch,throw,noexcept(C11)7. 运算符关键字new,delete,new[],delete[]sizeof,alignof(C11)typeid,dynamic_cast,static_cast,const_cast,reinterpret_castoperator8. 其他重要关键字namespace,using,asmalignas(C11),alignof(C11)decltype(C11),auto(类型推导C11)nullptr(C11),constexpr(C11)完整的关键字示例#includeiostream#includetypeinfo// 演示多种关键字的使用classBase{public:virtualvoidprint()const{std::coutBase classstd::endl;}virtual~Base()default;};classDerivedfinal:publicBase{// final关键字防止进一步继承public:voidprint()constoverride{// override确保正确重写虚函数std::coutDerived classstd::endl;}};templatetypenameTclassTemplateClass{private:T value;public:explicitTemplateClass(T val):value(val){}TgetValue()const{returnvalue;}};intmain(){// auto类型推导autox10;// x被推导为intautoy3.14;// y被推导为doubleautozhello;// z被推导为const char*// constexpr编译时常量constexprintarray_size100;intarr[array_size];// nullptr空指针int*ptrnullptr;// dynamic_cast运行时类型检查Base*basePtrnewDerived();if(Derived*derivedPtrdynamic_castDerived*(basePtr)){derivedPtr-print();}deletebasePtr;return0;}二、命名空间命名空间是C中用于组织代码、防止命名冲突的重要机制。在大型项目中不同模块可能使用相同的标识符命名空间可以有效地解决这个问题。1. 命名空间定义命名空间可以包含变量、函数、类、模板等任何合法的C实体。#includeiostream#includestring#includevector// 基本命名空间定义namespaceMath{constdoublePI3.141592653589793;doubleadd(doublea,doubleb){returnab;}doublemultiply(doublea,doubleb){returna*b;}// 命名空间内可以嵌套类classCalculator{public:staticdoublepower(doublebase,intexponent){doubleresult1.0;for(inti0;iexponent;i){result*base;}returnresult;}};}// 命名空间可以分段定义namespaceMath{// 可以继续添加成员doublesubtract(doublea,doubleb){returna-b;}// 嵌套命名空间namespaceConstants{constdoubleE2.718281828459045;constdoubleGOLDEN_RATIO1.618033988749895;}}// 匿名命名空间仅在当前文件内可见namespace{intinternalVariable42;voidinternalFunction(){std::coutThis is an internal functionstd::endl;}}// 命名空间别名namespaceVeryLongNamespaceName{voidfunction(){std::coutFunction in very long namespacestd::endl;}}// 创建别名namespaceVLNVeryLongNamespaceName;// 内联命名空间C11inlinenamespaceVersion1{voidapi(){std::coutVersion 1 APIstd::endl;}}namespaceVersion2{voidapi(){std::coutVersion 2 APIstd::endl;}}// 使用内联命名空间namespaceLibrary{inlinenamespaceCurrent{voidfeature(){std::coutCurrent featurestd::endl;}}namespaceDeprecated{voidfeature(){std::coutDeprecated featurestd::endl;}}}2. 命名空间的使用#includeiostream#includestringnamespaceCompany{namespaceDepartment{namespaceTeam{classEmployee{private:std::string name;intid;public:Employee(std::string n,inti):name(n),id(i){}voiddisplay()const{std::coutEmployee: name, ID: idstd::endl;}};}}}// 方法1使用完全限定名voidmethod1(){Company::Department::Team::Employeeemp1(Alice,1001);emp1.display();}// 方法2使用using声明voidmethod2(){usingCompany::Department::Team::Employee;Employeeemp2(Bob,1002);emp2.display();}// 方法3使用using指令voidmethod3(){usingnamespaceCompany::Department::Team;Employeeemp3(Charlie,1003);emp3.display();}// 方法4使用命名空间别名voidmethod4(){namespaceCDTCompany::Department::Team;CDT::Employeeemp4(David,1004);emp4.display();}// 演示using声明的作用域voiddemonstrateScope(){// 局部using声明{usingstd::cout;usingstd::endl;coutInside block with using declarationsendl;}// cout和endl在这里不可用除非全局使用// cout This would cause error endl;}// 处理命名冲突namespaceGraphics{classPoint{public:intx,y;Point(intx,inty):x(x),y(y){}};}namespacePhysics{classPoint{public:doublex,y,z;Point(doublex,doubley,doublez):x(x),y(y),z(z){}};}voidhandleNamingConflict(){Graphics::PointgPoint(10,20);Physics::PointpPoint(1.0,2.0,3.0);std::coutGraphics Point: (gPoint.x, gPoint.y)std::endl;std::coutPhysics Point: (pPoint.x, pPoint.y, pPoint.z)std::endl;}// 标准库命名空间使用示例voidstdNamespaceExample(){usingstd::cout;usingstd::endl;usingstd::string;usingstd::vector;string nameC Programming;vectorintnumbers{1,2,3,4,5};coutString: nameendl;coutNumbers: ;for(intnum:numbers){coutnum ;}coutendl;}// 内联命名空间使用voidinlineNamespaceExample(){// 可以直接访问内联命名空间的成员Library::feature();// 使用当前版本// 也可以明确指定版本Library::Current::feature();Library::Deprecated::feature();}intmain(){std::cout Namespace Usage Examples std::endl;method1();method2();method3();method4();demonstrateScope();handleNamingConflict();stdNamespaceExample();inlineNamespaceExample();// 使用Math命名空间std::cout\n Math Namespace Examples std::endl;std::coutPI: Math::PIstd::endl;std::coutAdd: Math::add(10.5,20.3)std::endl;std::coutEulers number: Math::Constants::Estd::endl;std::coutPower: Math::Calculator::power(2,8)std::endl;return0;}三、C输入输出C使用流stream进行输入输出操作这是一种更安全、更灵活的方式相比于C语言的printf/scanfC的I/O支持类型安全、可扩展性更好。基础输入输出#includeiostream// 包含标准输入输出流#includeiomanip// 包含I/O操作符#includestring#includelimitsvoidbasicIO(){// 标准输出std::coutHello, World!std::endl;// 输出多个值intage25;doublesalary75000.50;std::string nameJohn Doe;std::coutName: name, Age: age, Salary: salarystd::endl;// 标准输入intnumber;std::coutEnter an integer: ;std::cinnumber;std::coutYou entered: numberstd::endl;// 输入多个值inta,b;std::coutEnter two integers: ;std::cinab;std::coutSum: abstd::endl;}// 格式化输出voidformattedOutput(){// 设置宽度和对齐std::coutstd::setw(15)std::leftNamestd::setw(10)std::rightAgestd::setw(15)std::rightSalarystd::endl;std::coutstd::setw(15)std::leftAlicestd::setw(10)std::right30std::setw(15)std::rightstd::fixedstd::setprecision(2)85000.00std::endl;// 数字格式化doublepi3.141592653589793;std::cout\nDifferent formats of pi:std::endl;std::coutDefault: pistd::endl;std::coutFixed (2 decimal): std::fixedstd::setprecision(2)pistd::endl;std::coutScientific: std::scientificpistd::endl;// 重置格式std::cout.unsetf(std::ios::fixed|std::ios::scientific);std::coutstd::setprecision(6);// 恢复默认精度// 布尔值格式化boolflagtrue;std::cout\nBool as integer: flagstd::endl;std::coutstd::boolalphaBool as text: flagstd::noboolalphastd::endl;}// 字符串输入处理voidstringInput(){std::string fullName;// 清除输入缓冲区std::cin.ignore(std::numeric_limitsstd::streamsize::max(),\n);std::cout\nEnter your full name: ;std::getline(std::cin,fullName);// 读取整行std::coutHello, fullName!std::endl;// 逐个单词读取std::coutEnter three words: ;std::string word1,word2,word3;std::cinword1word2word3;std::coutWords: word1, word2, word3std::endl;}// 文件流状态检查voidstreamState(){intvalue;std::cout\nEnter an integer (enter abc to test error handling): ;std::cinvalue;// 检查输入状态if(std::cin.fail()){std::coutInvalid input! Clearing error state...std::endl;std::cin.clear();// 清除错误状态std::cin.ignore(std::numeric_limitsstd::streamsize::max(),\n);// 忽略错误输入}else{std::coutValid input: valuestd::endl;}}// 自定义类型的输入输出classPerson{private:std::string name;intage;public:Person(std::string n,inta0):name(n),age(a){}// 重载输出运算符friendstd::ostreamoperator(std::ostreamos,constPersonp){osPerson{namep.name, agep.age};returnos;}// 重载输入运算符friendstd::istreamoperator(std::istreamis,Personp){std::coutEnter name: ;isp.name;std::coutEnter age: ;isp.age;returnis;}};voidcustomTypeIO(){Personp1(Alice,30);Person p2;std::cout\n Custom Type I/O std::endl;std::coutPerson 1: p1std::endl;std::cout\nEnter details for Person 2:std::endl;std::cinp2;std::coutPerson 2: p2std::endl;}// 二进制输入输出简单示例voidbinaryIOExample(){// 注意这里仅展示概念实际文件操作需要包含fstreamintnumbers[]{1,2,3,4,5};std::cout\n Binary Representation std::endl;// 以十六进制显示内存表示unsignedchar*bytesreinterpret_castunsignedchar*(numbers);for(inti0;isizeof(numbers);i){std::coutstd::hexstd::setw(2)std::setfill(0)static_castint(bytes[i]) ;if((i1)%40)std::cout ;}std::coutstd::decstd::endl;}intmain(){std::cout C Input/Output Examples std::endl;basicIO();formattedOutput();stringInput();streamState();customTypeIO();binaryIOExample();return0;}高级I/O特性#includeiostream#includeiomanip#includesstream// 字符串流#includefstream// 文件流#includevector// 字符串流示例voidstringStreamDemo(){std::cout\n String Stream Demo std::endl;// 将数据写入字符串流std::ostringstream oss;ossPI 3.14159, E 2.71828;std::string resultoss.str();std::coutOutput string: resultstd::endl;// 从字符串读取数据std::string data100 3.14 Hello;std::istringstreamiss(data);intnum;doublevalue;std::string text;issnumvaluetext;std::coutParsed: num, value, textstd::endl;// 更复杂的解析std::string csvJohn,Doe,30,Engineer;std::replace(csv.begin(),csv.end(),,, );std::istringstreamcsvStream(csv);std::string firstName,lastName,job;intage;csvStreamfirstNamelastNameagejob;std::coutCSV Parsed: firstName lastName, age, jobstd::endl;}// 文件流示例voidfileStreamDemo(){std::cout\n File Stream Demo std::endl;// 写入文件std::ofstreamoutFile(example.txt);if(outFile.is_open()){outFileHello, File!\n;outFileThis is line 2\n;outFileValue: 42\n;outFile.close();std::coutFile written successfully.std::endl;}else{std::cerrFailed to open file for writing.std::endl;}// 读取文件std::ifstreaminFile(example.txt);if(inFile.is_open()){std::string line;std::cout\nFile contents:std::endl;while(std::getline(inFile,line)){std::coutlinestd::endl;}inFile.close();}// 二进制文件操作std::vectorintdata{1,2,3,4,5};// 写入二进制文件std::ofstreambinOut(data.bin,std::ios::binary);if(binOut.is_open()){binOut.write(reinterpret_castchar*(data.data()),data.size()*sizeof(int));binOut.close();}// 读取二进制文件std::ifstreambinIn(data.bin,std::ios::binary);if(binIn.is_open()){binIn.seekg(0,std::ios::end);size_t fileSizebinIn.tellg();binIn.seekg(0,std::ios::beg);std::vectorintreadData(fileSize/sizeof(int));binIn.read(reinterpret_castchar*(readData.data()),fileSize);binIn.close();std::cout\nBinary data read: ;for(intval:readData){std::coutval ;}std::coutstd::endl;}}// 流缓冲区操作voidstreamBufferDemo(){std::cout\n Stream Buffer Demo std::endl;// 重定向cout到stringstreamstd::ostringstream buffer;std::streambuf*oldCoutBufferstd::cout.rdbuf(buffer.rdbuf());std::coutThis goes to the buffer, not the screen!;std::cout More text in buffer.;// 恢复coutstd::cout.rdbuf(oldCoutBuffer);std::coutBuffer contains: buffer.str()std::endl;// 使用stringstream作为格式化工具std::stringstream ss;ssstd::hexstd::uppercasestd::setfill(0);intnum255;ss0xstd::setw(8)num;std::coutFormatted hex: ss.str()std::endl;}// 自定义流操作符std::ostreamcustomManipulator(std::ostreamos){osstd::setw(20)std::setfill(*);returnos;}voidcustomManipulatorDemo(){std::cout\n Custom Manipulator Demo std::endl;std::coutcustomManipulatorHellostd::endl;std::coutcustomManipulatorWorldstd::endl;}// 错误处理示例voiderrorHandlingDemo(){std::cout\n Error Handling Demo std::endl;std::ifstreamfile(nonexistent.txt);if(!file){std::cerrError: Could not open file!std::endl;perror(Detailed error);// C风格的错误信息}// 设置异常抛出std::ifstream file2;file2.exceptions(std::ifstream::failbit|std::ifstream::badbit);try{file2.open(nonexistent.txt);}catch(conststd::ifstream::failuree){std::cerrException caught: e.what()std::endl;}}intmain(){stringStreamDemo();fileStreamDemo();streamBufferDemo();customManipulatorDemo();errorHandlingDemo();return0;}四、缺省参数缺省参数是C中一个非常实用的特性它允许在函数声明时为参数指定默认值。当调用函数时如果没有提供该参数的值就会使用默认值。1. 缺省参数概念#includeiostream#includestring// 基本缺省参数示例voidprintMessage(conststd::stringmessageHello, World!,intrepeat1){for(inti0;irepeat;i){std::coutmessagestd::endl;}}// 带有复杂默认值的函数std::stringcreateGreeting(conststd::stringnameGuest,conststd::stringprefixHello,conststd::stringsuffix!){returnprefix namesuffix;}// 默认参数可以是表达式intgetDefaultValue(){return42;}voidfunctionWithExpression(intxgetDefaultValue(),doubley3.14*2){std::coutx x, y ystd::endl;}2. 缺省参数分类#includeiostream#includevector#includecmath// 1. 全缺省参数 - 所有参数都有默认值voiddrawRectangle(intwidth10,intheight5,charborder*,charfill ){for(inti0;iheight;i){for(intj0;jwidth;j){if(i0||iheight-1||j0||jwidth-1){std::coutborder;}else{std::coutfill;}}std::coutstd::endl;}}// 2. 半缺省参数 - 部分参数有默认值// 注意半缺省参数必须从右向左连续doublecalculatePayment(doubleprincipal,doublerate,// 必须提供intyears1,// 可选intperiodsPerYear12){// 可选doublerrate/periodsPerYear;intnyears*periodsPerYear;returnprincipal*r*pow(1r,n)/(pow(1r,n)-1);}// 3. 带有复杂默认值的半缺省参数voidlogMessage(conststd::stringmessage,conststd::stringlevelINFO,std::ostreamoutputstd::cout,booltimestamptrue){if(timestamp){// 这里可以添加时间戳逻辑output[TIMESTAMP] ;}output[level] messagestd::endl;}// 4. 类成员函数中的缺省参数classConfiguration{private:inttimeout;intretries;boolverbose;public:// 构造函数使用缺省参数Configuration(intt30,intr3,boolvfalse):timeout(t),retries(r),verbose(v){}// 成员函数使用缺省参数voidsetSettings(intt30,intr3,boolvfalse){timeoutt;retriesr;verbosev;}voiddisplay()const{std::coutTimeout: timeout, Retries: retries, Verbose: (verbose?true:false)std::endl;}};// 5. 模板函数中的缺省参数templatetypenameTint,typenameUdoubleclassPair{private:T first;U second;public:Pair(T fT{},U sU{}):first(f),second(s){}voiddisplay()const{std::cout(first, second)std::endl;}};// 6. 继承中的缺省参数classBase{public:virtualvoiddisplay(intx10){std::coutBase: xstd::endl;}};classDerived:publicBase{public:// 注意重写函数不会继承默认参数voiddisplay(intx20)override{std::coutDerived: xstd::endl;}};// 7. 函数指针中的缺省参数typedefvoid(*PrintFunc)(conststd::string,int);voiddemonstrateFunctionPointer(){PrintFunc funcprintMessage;func(Hello via function pointer,2);}// 8. 缺省参数的常见陷阱voidtrickyExample(intx,intyx){// 错误不能使用参数作为默认值// 正确的做法// void trickyExample(int x, int y 0)}// 9. 使用constexpr作为默认参数constexprintgetDefaultSize(){return100;}classArrayWrapper{private:int*data;intsize;public:// 使用constexpr函数作为默认参数ArrayWrapper(intszgetDefaultSize()):size(sz){datanewint[size]{};}~ArrayWrapper(){delete[]data;}};// 10. 可变参数模板与缺省参数结合templatetypename...ArgsvoidlogWithDefaults(conststd::stringmessage,Args...args){// 这里可以处理可变参数std::coutmessage;((std::cout std::forwardArgs(args)),...);std::coutstd::endl;}// 测试函数voidtestDefaultParameters(){std::cout Testing Default Parameters std::endl;// 全缺省参数测试std::cout\n1. Drawing rectangles with defaults:std::endl;drawRectangle();// 使用所有默认值std::cout\nCustom rectangle:std::endl;drawRectangle(15,8,#,.);// 提供所有参数// 半缺省参数测试std::cout\n2. Loan calculations:std::endl;std::coutMonthly payment: $calculatePayment(100000,0.05)std::endl;// 1年12期std::coutMonthly payment: $calculatePayment(100000,0.05,30)std::endl;// 30年// 类成员函数测试std::cout\n3. Configuration class:std::endl;Configuration config1;// 使用所有默认值Configurationconfig2(60,5,true);// 提供所有值config1.display();config2.display();// 模板类测试std::cout\n4. Template class with defaults:std::endl;Pairp1;// 使用默认类型int, doublePairstd::stringp2(Hello,3.14);// 指定第一个类型p1.display();p2.display();// 继承中的缺省参数问题std::cout\n5. Inheritance and default parameters:std::endl;Base*basenewDerived();base-display();// 输出什么答案是Derived: 10deletebase;// 函数指针测试std::cout\n6. Function pointers:std::endl;demonstrateFunctionPointer();// 日志函数测试std::cout\n7. Logging with defaults:std::endl;logMessage(Application started);logMessage(Error occurred,ERROR,std::cerr,false);}// 实际应用示例配置系统classDatabaseConfig{private:std::string host;intport;std::string username;std::string password;inttimeout;booluseSSL;public:DatabaseConfig(conststd::stringhlocalhost,intp5432,conststd::stringuadmin,conststd::stringpw,intt30,boolssltrue):host(h),port(p),username(u),password(pw),timeout(t),useSSL(ssl){}voiddisplay()const{std::coutDatabase Config:std::endl Host: hoststd::endl Port: portstd::endl Username: usernamestd::endl Timeout: timeoutsstd::endl SSL: (useSSL?Enabled:Disabled)std::endl;}};intmain(){testDefaultParameters();std::cout\n Real-world Example: Database Config std::endl;DatabaseConfig defaultConfig;DatabaseConfigcustomConfig(db.example.com,3306,root,secret123,60,false);defaultConfig.display();std::coutstd::endl;customConfig.display();return0;}五、函数重载函数重载是C的重要特性之一它允许在同一作用域内定义多个同名函数只要它们的参数列表不同。1. 函数重载概念#includeiostream#includestring#includevector#includecmath// 基本函数重载示例classMathOperations{public:// 1. 参数类型不同的重载intadd(inta,intb){std::coutAdding integers: ;returnab;}doubleadd(doublea,doubleb){std::coutAdding doubles: ;returnab;}// 2. 参数数量不同的重载intadd(inta,intb,intc){std::coutAdding three integers: ;returnabc;}// 3. 参数顺序不同的重载需要不同类型voidprint(inta,doubleb){std::coutint: a, double: bstd::endl;}voidprint(doublea,intb){std::coutdouble: a, int: bstd::endl;}// 4. const重载voidprocess(std::stringstr){std::coutProcessing mutable string: strstd::endl;str (modified);}voidprocess(conststd::stringstr){std::coutProcessing const string: strstd::endl;}// 5. 指针和引用重载voiddisplay(int*ptr){std::coutPointer to int: *ptrstd::endl;}voiddisplay(intref){std::coutReference to int: refstd::endl;}// 6. 带默认参数的重载voidcalculate(inta,intb10){std::coutCalculate with default: abstd::endl;}voidcalculate(inta){std::coutCalculate single: astd::endl;}};// 运算符重载特殊形式的函数重载classComplex{private:doublereal;doubleimag;public:Complex(doubler0,doublei0):real(r),imag(i){}// 运算符重载Complexoperator(constComplexother)const{returnComplex(realother.real,imagother.imag);}Complexoperator-(constComplexother)const{returnComplex(real-other.real,imag-other.imag);}// 友元函数形式的运算符重载friendstd::ostreamoperator(std::ostreamos,constComplexc);// 前缀重载Complexoperator(){real;imag;return*this;}// 后缀重载Complexoperator(int){Complex temp*this;(*this);returntemp;}};std::ostreamoperator(std::ostreamos,constComplexc){osc.real c.imagi;returnos;}// 模板函数重载templatetypenameTTmaximum(T a,T b){std::coutTemplate max for two values: ;return(ab)?a:b;}templatetypenameTTmaximum(T a,T b,T c){std::coutTemplate max for three values: ;returnmaximum(maximum(a,b),c);}// 重载解析示例voidoverloadResolutionDemo(){MathOperations math;std::cout Overload Resolution Examples std::endl;// 1. 精确匹配std::coutmath.add(10,20)std::endl;// 调用int版本std::coutmath.add(10.5,20.3)std::endl;// 调用double版本// 2. 类型转换匹配std::coutmath.add(10,20.5)std::endl;// 调用哪个double版本// 3. 参数数量匹配std::coutmath.add(1,2,3)std::endl;// 4. const重载std::string strHello;conststd::string constStrWorld;math.process(str);// 调用非常量版本math.process(constStr);// 调用常量版本// 5. 指针和引用重载intvalue42;int*ptrvalue;math.display(ptr);// 调用指针版本math.display(value);// 调用引用版本// 6. 默认参数带来的歧义// math.calculate(5); // 错误ambiguous callmath.calculate(5,10);// OKstd::cout\n Operator Overloading std::endl;Complexc1(3,4);Complexc2(1,2);Complex c3c1c2;std::coutc1 c2 c3std::endl;std::cout\n Template Function Overloading std::endl;std::coutmaximum(10,20)std::endl;std::coutmaximum(10,20,15)std::endl;std::coutmaximum(3.14,2.71)std::endl;}// 重载函数的最佳实践classStringUtils{public:// 避免过度重载staticstd::stringtrim(conststd::stringstr){returntrim(str, \t\n\r);}staticstd::stringtrim(conststd::stringstr,conststd::stringdelimiters){size_t firststr.find_first_not_of(delimiters);if(firststd::string::npos)return;size_t laststr.find_last_not_of(delimiters);returnstr.substr(first,last-first1);}// 使用重载提供便捷接口staticvoidlog(conststd::stringmessage){log(message,INFO,std::cout);}staticvoidlog(conststd::stringmessage,conststd::stringlevel){log(message,level,std::cout);}staticvoidlog(conststd::stringmessage,conststd::stringlevel,std::ostreamoutput){output[level] messagestd::endl;}};// 重载与继承classBaseLogger{public:virtualvoidlog(conststd::stringmessage){std::coutBase: messagestd::endl;}// 重载函数virtualvoidlog(conststd::stringmessage,intseverity){std::coutBase[severity]: messagestd::endl;}};classFileLogger:publicBaseLogger{public:// 只重写一个版本voidlog(conststd::stringmessage)override{std::coutFile: messagestd::endl;}// 另一个版本仍然可用继承自基类};// 测试继承中的重载voidtestInheritanceOverloading(){FileLogger logger;logger.log(Simple message);// 调用派生类版本logger.log(Important,1);// 调用基类版本BaseLogger*basePtrlogger;basePtr-log(Polymorphic);// 多态调用派生类版本basePtr-log(Polymorphic,2);// 调用基类版本}intmain(){overloadResolutionDemo();std::cout\n String Utils Examples std::endl;std::string testStr Hello World ;std::coutTrimmed: StringUtils::trim(testStr)std::endl;StringUtils::log(Application started);StringUtils::log(Error occurred,ERROR);std::cout\n Inheritance and Overloading std::endl;testInheritanceOverloading();return0;}2. C支持函数重载的原理——名字修饰#includeiostream#includestring// 名字修饰Name Mangling演示// C编译器会对函数名进行修饰以支持函数重载// 使用extern C禁用名字修饰externC{// C风格函数没有名字修饰voidc_style_function(intx){std::coutC style function: xstd::endl;}// C语言不支持函数重载所以不能这样定义// void c_style_function(double x); // 错误}// C风格函数支持重载voidcpp_style_function(intx){std::coutC int function: xstd::endl;}voidcpp_style_function(doublex){std::coutC double function: xstd::endl;}voidcpp_style_function(intx,doubley){std::coutC int, double function: x, ystd::endl;}// 查看名字修饰// 编译时可以使用 nm 命令查看符号表// nm ./executable | grep function// 演示不同编译器可能的不同名字修饰classDemoClass{public:voidmember_function(){}voidmember_function(int){}staticvoidstatic_function(){}virtualvoidvirtual_function(){}};// 模板函数的名字修饰templatetypenameTvoidtemplate_function(T value){std::coutTemplate: valuestd::endl;}// 特化版本templatevoidtemplate_functionint(intvalue){std::coutSpecialized for int: valuestd::endl;}// 演示名字空间对名字修饰的影响namespaceOuter{namespaceInner{voidnested_function(){}}}// 演示extern C的实际应用// 在C中调用C库函数externC{// 假设这是C库中的函数声明intc_library_function(constchar*str);}// 创建可以从C调用的C函数externC{intcpp_function_callable_from_c(intx,inty){returnxy;}}// 名字修饰的实际影响voiddemonstrateNameMangling(){std::cout Name Mangling Demonstration std::endl;// 调用C风格函数没有重载c_style_function(10);// 调用C风格函数支持重载cpp_style_function(10);cpp_style_function(3.14);cpp_style_function(10,3.14);// 调用模板函数template_function(10);template_function(3.14);template_function(Hello);// 调用命名空间中的函数Outer::Inner::nested_function();// 演示调用约定DemoClass obj;obj.member_function();obj.member_function(10);DemoClass::static_function();// 虚函数调用obj.virtual_function();}// 使用工具分析名字修饰voidanalyzeNameMangling(){std::cout\n Name Mangling Analysis std::endl;// 在不同编译器下修饰后的名字可能不同// GCC/Clang: _Z10some_functioni// MSVC: ?some_functionYAXHZ// 可以这样查看// 1. 编译时添加 -S 生成汇编代码// 2. 使用 nm 命令查看符号表// 3. 使用 cfilt 工具反修饰名字std::coutTo see mangled names, compile with:std::endl;std::cout g -S source.cpp # Generate assemblystd::endl;std::cout nm executable # Show symbolsstd::endl;std::cout cfilt symbol # Demangle namesstd::endl;}// 跨语言调用的实际例子// 假设有一个C库我们需要在C中使用#ifdef__cplusplusexternC{#endif// C库的头文件应该这样包装typedefstruct{intx;inty;}Point;voidc_draw_point(Point p);voidc_draw_line(Point p1,Point p2);#ifdef__cplusplus}#endif// C包装器classGraphicsWrapper{public:staticvoiddrawPoint(intx,inty){Point p{x,y};c_draw_point(p);}staticvoiddrawLine(intx1,inty1,intx2,inty2){Point p1{x1,y1};Point p2{x2,y2};c_draw_line(p1,p2);}};// 演示C调用C函数// C端定义externC{voidcpp_callback(intvalue){std::coutC callback: valuestd::endl;}}// 模拟C端调用externC{voidc_function_that_calls_cpp(void(*callback)(int)){callback(42);}}intmain(){demonstrateNameMangling();analyzeNameMangling();std::cout\n Cross-language Calling std::endl;// 模拟C调用C回调函数c_function_that_calls_cpp(cpp_callback);// 使用C包装器调用C函数GraphicsWrapper::drawPoint(10,20);GraphicsWrapper::drawLine(0,0,100,100);return0;}六、引用引用是C中一个强大而独特的特性它为变量创建别名提供了更安全和直观的操作方式。1. 引用概念#includeiostream#includestring#includevector// 基本引用示例voidbasicReferences(){std::cout Basic References std::endl;intoriginal42;intreforiginal;// ref是original的引用别名std::coutoriginal: originalstd::endl;std::coutref: refstd::endl;std::coutoriginal: originalstd::endl;std::coutref: refstd::endl;// 地址相同// 通过引用修改值ref100;std::coutAfter modification:std::endl;std::coutoriginal: originalstd::endl;// 也变成100std::coutref: refstd::endl;// 引用必须在声明时初始化// int invalidRef; // 错误必须初始化}// 引用作为函数参数voidswap(inta,intb){inttempa;ab;btemp;}voidmodifyString(std::stringstr){str (modified);}// 返回引用intgetElement(std::vectorintvec,size_t index){if(indexvec.size()){returnvec[index];}throwstd::out_of_range(Index out of range);}// 常量引用voidprintVector(conststd::vectorintvec){std::coutVector elements: ;for(constintnum:vec){// 使用常量引用避免拷贝std::coutnum ;}std::coutstd::endl;}2. 引用特性#includeiostream#includestring// 1. 引用必须在定义时初始化voidreferenceInitialization(){std::cout\n Reference Initialization std::endl;intx10;// 正确定义时初始化intref1x;// 错误未初始化// int ref2;// 引用不能重新绑定inty20;// ref1 y; // 这不是重新绑定而是赋值std::coutx: x, ref1: ref1std::endl;ref1y;// 这会将x的值改为20std::coutAfter ref1 y:std::endl;std::coutx: x, y: y, ref1: ref1std::endl;}// 2. 引用类型必须匹配voidreferenceTypeMatching(){std::cout\n Reference Type Matching std::endl;inti10;constintci20;intrii;// OK// int rci ci; // 错误不能将非常量引用绑定到常量constintrci2ci;// OK常量引用绑定到常量constintrci3i;// OK常量引用可以绑定到非常量// 临时对象的引用constinttempRef42;// OK常量引用可以绑定到临时对象// int tempRef2 42; // 错误非常量引用不能绑定到临时对象}// 3. 引用与指针的区别voidreferenceVsPointer(){std::cout\n Reference vs Pointer std::endl;intvalue100;int*ptrvalue;// 指针需要取地址intrefvalue;// 引用直接初始化std::coutvalue: valuestd::endl;std::coutptr: ptr, *ptr: *ptrstd::endl;std::coutref: refstd::endl;// 修改值*ptr200;std::coutAfter *ptr 200:std::endl;std::coutvalue: value, ref: refstd::endl;ref300;std::coutAfter ref 300:std::endl;std::coutvalue: value, *ptr: *ptrstd::endl;// 指针可以改变指向引用不能intanother500;ptranother;// OK// ref another; // 错误不能重新绑定这是赋值}// 4. 引用数组和数组引用voidarrayReferences(){std::cout\n Array References std::endl;intarr[5]{1,2,3,4,5};// 数组的引用int(arrRef)[5]arr;// arrRef是数组的引用std::coutArray elements via reference: ;for(inti0;i5;i){std::coutarrRef[i] ;}std::coutstd::endl;// 不能创建引用数组数组元素不能是引用// int refArr[5]; // 错误}// 5. 引用在范围for循环中的应用voidrangeForWithReferences(){std::cout\n Range-based for with References std::endl;std::vectorintnumbers{1,2,3,4,5};std::coutOriginal: ;for(constautonum:numbers){std::coutnum ;}std::coutstd::endl;// 使用引用修改元素std::coutModifying elements: ;for(autonum:numbers){num*2;std::coutnum ;}std::coutstd::endl;std::coutAfter modification: ;for(constautonum:numbers){std::coutnum ;}std::coutstd::endl;}// 6. 引用在类成员函数中的应用classBigData{private:std::vectorintdata;public:BigData(){// 创建大量数据for(inti0;i1000;i){data.push_back(i);}}// 返回常量引用避免拷贝conststd::vectorintgetData()const{returndata;}// 返回引用允许修改std::vectorintgetMutableData(){returndata;}};voidclassMemberReferences(){std::cout\n Class Member References std::endl;BigData bigData;// 获取常量引用只读访问conststd::vectorintconstDatabigData.getData();std::coutData size: constData.size()std::endl;// 获取非常量引用可以修改std::vectorintmutableDatabigData.getMutableData();mutableData.push_back(1000);std::coutNew data size: mutableData.size()std::endl;}// 7. 右值引用C11voidrvalueReferences(){std::cout\n Rvalue References (C11) std::endl;intx10;// 左值引用intlrefx;// 绑定到左值// 右值引用intrref20;// 绑定到右值临时对象std::coutx: xstd::endl;std::coutlref: lrefstd::endl;std::coutrref: rrefstd::endl;// 移动语义示例std::vectorintsource{1,2,3,4,5};std::coutSource size before move: source.size()std::endl;// 使用移动语义std::vectorintdestinationstd::move(source);std::coutSource size after move: source.size()std::endl;std::coutDestination size: destination.size()std::endl;}// 8. 引用折叠和完美转发templatetypenameTvoidforwardExample(Targ){// 引用折叠规则// T - T// T - T// T - T// T - Tprocess(std::forwardT(arg));}voidprocess(intx){std::coutprocess(lvalue): xstd::endl;}voidprocess(intx){std::coutprocess(rvalue): xstd::endl;}voidtestPerfectForwarding(){std::cout\n Perfect Forwarding std::endl;intx10;forwardExample(x);// 调用process(int)forwardExample(20);// 调用process(int)}// 9. 引用在函数式编程中的应用voidfunctionalProgrammingWithReferences(){std::cout\n Functional Programming with References std::endl;autoadder[](inttotal,intvalue){totalvalue;returntotal;};intsum0;std::vectorintnumbers{1,2,3,4,5};for(intnum:numbers){adder(sum,num);}std::coutSum: sumstd::endl;// 使用std::accumulatesum0;for(constintnum:numbers){sumnum;}std::coutSum (manual): sumstd::endl;}// 10. 引用陷阱和最佳实践voidreferencePitfalls(){std::cout\n Reference Pitfalls std::endl;// 陷阱1返回局部变量的引用/* int badReference() { int local 42; return local; // 错误返回局部变量的引用 } */// 陷阱2悬垂引用int*ptrnewint(100);intref*ptr;deleteptr;// ref现在指向已释放的内存// 最佳实践使用常量引用作为函数参数autogoodPractice[](conststd::stringstr){// 安全不会意外修改输入returnstr.length();};std::string testHello;std::coutLength: goodPractice(test)std::endl;}intmain(){basicReferences();referenceInitialization();referenceTypeMatching();referenceVsPointer();arrayReferences();rangeForWithReferences();classMemberReferences();rvalueReferences();testPerfectForwarding();functionalProgrammingWithReferences();referencePitfalls();// 演示swap函数std::cout\n Swap Function Demo std::endl;inta10,b20;std::coutBefore swap: aa, bbstd::endl;swap(a,b);std::coutAfter swap: aa, bbstd::endl;return0;}七、内联函数内联函数是C中用于提高程序性能的重要特性它可以减少函数调用的开销。1. 概念#includeiostream#includechrono#includevector// 基本内联函数示例inlineintsquare(intx){returnx*x;}// 类内的内联函数classMathUtils{public:// 隐式内联在类定义内实现的成员函数intcube(intx){returnx*x*x;}// 显式内联inlinedoublereciprocal(doublex){return1.0/x;}// 类外定义的内联函数doublepower(doublebase,intexponent);};// 类外定义内联函数inlinedoubleMathUtils::power(doublebase,intexponent){doubleresult1.0;for(inti0;iexponent;i){result*base;}returnresult;}// 模板函数通常是内联的templatetypenameTinlineTmax(T a,T b){return(ab)?a:b;}// 递归函数通常不应该内联但编译器可能会优化inlineintfactorial(intn){return(n1)?1:n*factorial(n-1);}// 性能测试比较内联和非内联函数classPerformanceTest{public:// 非内联函数intnonInlineAdd(inta,intb){returnab;}// 内联函数inlineintinlineAdd(inta,intb){returnab;}// 测试性能voidrunTest(){constintiterations100000000;intresult0;autostartstd::chrono::high_resolution_clock::now();for(inti0;iiterations;i){resultnonInlineAdd(i,i1);}autoendstd::chrono::high_resolution_clock::now();autoduration1std::chrono::duration_caststd::chrono::milliseconds(end-start);startstd::chrono::high_resolution_clock::now();for(inti0;iiterations;i){resultinlineAdd(i,i1);}endstd::chrono::high_resolution_clock::now();autoduration2std::chrono::duration_caststd::chrono::milliseconds(end-start);std::coutNon-inline function time: duration1.count()msstd::endl;std::coutInline function time: duration2.count()msstd::endl;std::coutDifference: duration1.count()-duration2.count()msstd::endl;}};// 内联函数的最佳实践classVector2D{private:doublex,y;public:Vector2D(doublex0,doubley0):x(x),y(y){}// 简单的getter/setter适合内联inlinedoublegetX()const{returnx;}inlinedoublegetY()const{returny;}inlinevoidsetX(doublenewX){xnewX;}inlinevoidsetY(doublenewY){ynewY;}// 简单的运算适合内联inlinedoublemagnitude()const{returnsqrt(x*xy*y);}// 复杂的函数不适合内联Vector2Dnormalize()const;};// 复杂函数在类外定义不内联Vector2DVector2D::normalize()const{doublemagmagnitude();if(mag0)returnVector2D();returnVector2D(x/mag,y/mag);}// 内联函数的限制voidinlineLimitations(){std::cout Inline Function Limitations std::endl;// 内联函数不能有循环或递归但某些编译器可能会处理// 内联只是建议编译器可能忽略// 获取函数地址int(*funcPtr)(int)square;std::coutAddress of square function: (void*)funcPtrstd::endl;std::coutsquare(5) funcPtr(5)std::endl;}// 现代C中的constexpr函数constexprintconstexprSquare(intx){returnx*x;}// constexpr函数在编译时计算voidconstexprDemo(){std::cout\n Constexpr Functions std::endl;// 编译时计算constexprintsizeconstexprSquare(10);intarray[size];// 使用编译时常量作为数组大小std::coutCompile-time square of 10: sizestd::endl;// 运行时也可以使用intx5;intresultconstexprSquare(x);std::coutRuntime square of 5: resultstd::endl;}// 内联变量C17inlineconstexprdoublePI3.141592653589793;// 内联命名空间变量namespaceConstants{inlineconstexprdoubleGRAVITY9.8;inlineconstexprdoubleLIGHT_SPEED299792458.0;}// 测试内联函数voidtestInlineFunctions(){std::cout Inline Function Testing std::endl;MathUtils math;// 测试各种内联函数std::coutsquare(5) square(5)std::endl;std::coutmath.cube(3) math.cube(3)std::endl;std::coutmath.reciprocal(4) math.reciprocal(4)std::endl;std::coutmath.power(2, 8) math.power(2,8)std::endl;// 测试模板内联函数std::coutmax(10, 20) max(10,20)std::endl;std::coutmax(3.14, 2.71) max(3.14,2.71)std::endl;// 测试递归内联函数std::coutfactorial(5) factorial(5)std::endl;// 测试内联变量std::cout\nInline variables:std::endl;std::coutPI PIstd::endl;std::coutGravity Constants::GRAVITYstd::endl;}// 实际应用几何计算库classGeometry{public:// 内联的几何计算函数staticinlinedoublecircleArea(doubleradius){returnPI*radius*radius;}staticinlinedoublecircleCircumference(doubleradius){return2*PI*radius;}staticinlinedoubletriangleArea(doublebase,doubleheight){return0.5*base*height;}staticinlinedoubledistance(doublex1,doubley1,doublex2,doubley2){doubledxx2-x1;doubledyy2-y1;returnsqrt(dx*dxdy*dy);}};intmain(){testInlineFunctions();inlineLimitations();constexprDemo();// 性能测试std::cout\n Performance Test std::endl;PerformanceTest test;test.runTest();// 几何计算示例std::cout\n Geometry Calculations std::endl;std::coutCircle area (r5): Geometry::circleArea(5)std::endl;std::coutCircle circumference (r5): Geometry::circleCircumference(5)std::endl;std::coutTriangle area (b10, h5): Geometry::triangleArea(10,5)std::endl;std::coutDistance (0,0) to (3,4): Geometry::distance(0,0,3,4)std::endl;return0;}八、auto关键字C11auto关键字是C11引入的一个重要特性它实现了类型自动推导让代码更简洁易读。#includeiostream#includevector#includemap#includestring#includetypeinfo#includememory#includefunctional// 1. 基本auto用法voidbasicAutoUsage(){std::cout Basic auto Usage std::endl;// 基本类型推导autox10;// intautoy3.14;// doubleautozHello;// const char*autoflagtrue;// boolstd::coutx type: typeid(x).name(), value: xstd::endl;std::couty type: typeid(y).name(), value: ystd::endl;std::coutz type: typeid(z).name(), value: zstd::endl;std::coutflag type: typeid(flag).name(), value: flagstd::endl;// 带修饰符的autoconstautocx100;// const intautorxx;// intconstautocrxx;// const intautourxx;// int (左值引用)autourv42;// int (右值引用)// 数组推导intarr[]{1,2,3,4,5};autoarrAutoarr;// int* (数组退化为指针)autoarrRefarr;// int()[5] (数组引用)std::coutarr size via auto: sizeof(arr)std::endl;// 20std::coutarrAuto size: sizeof(arrAuto)std::endl;// 8 (指针大小)std::coutarrRef size: sizeof(arrRef)std::endl;// 20}// 2. auto与容器迭代器voidautoWithContainers(){std::cout\n auto with Containers std::endl;std::vectorintnumbers{1,2,3,4,5};std::mapstd::string,intscores{{Alice,90},{Bob,85},{Charlie,92}};// 传统迭代器写法for(std::vectorint::iterator itnumbers.begin();it!numbers.end();it){std::cout*it ;}std::coutstd::endl;// 使用auto简化for(autoitnumbers.begin();it!numbers.end();it){std::cout*it ;}std::coutstd::endl;// 遍历mapfor(autoitscores.begin();it!scores.end();it){std::coutit-first: it-secondstd::endl;}// 更简洁的范围for循环配合autofor(constautonum:numbers){std::coutnum ;}std::coutstd::endl;for(constauto[name,score]:scores){// C17结构化绑定std::coutname: scorestd::endl;}}// 3. auto与函数返回值// C14开始支持函数返回类型推导autoadd(inta,intb)-int{// 尾随返回类型returnab;}// C14: 自动推导返回类型automultiply(inta,intb){returna*b;}// 推导复杂类型autocreateVector(){returnstd::vectorint{1,2,3,4,5};}// decltype(auto): 保持引用和const性质intglobal42;constintgetGlobal(){returnglobal;}voidreturnTypeDeduction(){std::cout\n Return Type Deduction std::endl;autoresult1add(10,20);autoresult2multiply(10,20);autoveccreateVector();std::coutadd(10, 20) result1std::endl;std::coutmultiply(10, 20) result2std::endl;std::coutVector size: vec.size()std::endl;// decltype(auto)示例autoxgetGlobal();// int (去掉引用和const)decltype(auto)ygetGlobal();// const int (保持原样)std::coutauto x type: typeid(x).name()std::endl;std::coutdecltype(auto) y type: typeid(y).name()std::endl;}// 4. auto与lambda表达式voidautoWithLambdas(){std::cout\n auto with Lambdas std::endl;// 传统lambda存储方式std::functionint(int,int)func1[](inta,intb){returnab;};// 使用auto简化autofunc2[](inta,intb){returnab;};// 自动推导参数类型 (C14)autofunc3[](autoa,autob){returnab;};// 泛型lambda (C20概念)autofunc4[]typenameT(T a,T b){returnab;};std::coutfunc1(10, 20) func1(10,20)std::endl;std::coutfunc2(10, 20) func2(10,20)std::endl;std::coutfunc3(10, 20) func3(10,20)std::endl;std::coutfunc3(3.14, 2.71) func3(3.14,2.71)std::endl;std::coutfunc4(10, 20) func4(10,20)std::endl;}// 5. auto与模板编程templatetypenameContainervoidprocessContainer(constContainercontainer){// 使用auto推导元素类型for(constautoelement:container){std::coutelement ;}std::coutstd::endl;}templatetypenameT1,typenameT2autoaddDifferentTypes(T1 a,T2 b)-decltype(ab){returnab;}voidautoWithTemplates(){std::cout\n auto with Templates std::endl;std::vectorintintVec{1,2,3};std::vectorstd::stringstrVec{Hello,World,C};processContainer(intVec);processContainer(strVec);autoresult1addDifferentTypes(10,3.14);// doubleautoresult2addDifferentTypes(std::string(Hello),std::string( World));// std::stringstd::coutaddDifferentTypes(10, 3.14) result1std::endl;std::coutaddDifferentTypes(string, string) result2std::endl;}// 6. auto陷阱和注意事项voidautoPitfalls(){std::cout\n auto Pitfalls std::endl;// 陷阱1推导出意外类型autox{1,2,3};// std::initializer_listint// auto y{1, 2, 3}; // C17前initializer_listC17错误// 陷阱2引用和const丢失constintci42;autoaci;// int (const丢失)autobci;// const int (正确)// 陷阱3auto和代理对象std::vectorboolboolVec{true,false,true};autoboolValboolVec[0];// std::vectorbool::reference (代理对象)// boolVal可能不是bool类型// 正确做法boolboolVal2boolVec[0];autoboolVal3static_castbool(boolVec[0]);// 陷阱4auto影响代码可读性autoresultsomeComplexFunction();// 类型不明确// 最佳实践在复杂情况下明确类型usingComplexTypestd::mapstd::string,std::vectorstd::pairint,double;ComplexType datagetComplexData();}// 7. auto在并发编程中的应用#includethread#includefuture#includeatomicvoidautoInConcurrency(){std::cout\n auto in Concurrency std::endl;// 自动推导线程autothreadFunc[](){std::coutThread running...std::endl;};autotstd::thread(threadFunc);t.join();// 自动推导futureautofuturestd::async([](){return42;});autoresultfuture.get();std::coutAsync result: resultstd::endl;// 原子变量autoatomicVarstd::atomicint{0};atomicVar.store(100);std::coutAtomic value: atomicVar.load()std::endl;}// 8. auto与现代C特性结合#includeoptional#includevariant#includeanyvoidautoWithModernCpp(){std::cout\n auto with Modern C std::endl;// optionalautomaybeValuestd::optionalint{42};if(maybeValue){std::coutOptional value: *maybeValuestd::endl;}// variantautovariantValuestd::variantint,double,std::string{3.14};std::visit([](autoarg){usingTstd::decay_tdecltype(arg);ifconstexpr(std::is_same_vT,int){std::coutVariant holds int: argstd::endl;}elseifconstexpr(std::is_same_vT,double){std::coutVariant holds double: argstd::endl;}elseifconstexpr(std::is_same_vT,std::string){std::coutVariant holds string: argstd::endl;}},variantValue);// anyautoanyValuestd::any{std::string(Hello)};try{autostrstd::any_caststd::string(anyValue);std::coutAny holds string: strstd::endl;}catch(conststd::bad_any_caste){std::coutBad any cast: e.what()std::endl;}}// 9. 实际应用示例配置文件解析classConfigParser{public:autoparse(conststd::stringfilename){// 模拟解析配置文件std::mapstd::string,std::mapstd::string,std::variantint,double,std::stringconfig;config[database][host]localhost;config[database][port]5432;config[database][timeout]30.5;config[server][max_connections]1000;config[server][enable_ssl]true;returnconfig;}};voidconfigExample(){std::cout\n Config Parser Example std::endl;ConfigParser parser;autoconfigparser.parse(config.ini);// 遍历配置for(constauto[section,values]:config){std::cout[section]std::endl;for(constauto[key,value]:values){std::cout key ;std::visit([](autoarg){usingTstd::decay_tdecltype(arg);ifconstexpr(std::is_same_vT,int){std::coutarg;}elseifconstexpr(std::is_same_vT,double){std::coutarg;}elseifconstexpr(std::is_same_vT,std::string){std::cout\arg\;}elseifconstexpr(std::is_same_vT,bool){std::cout(arg?true:false);}},value);std::coutstd::endl;}}}intmain(){basicAutoUsage();autoWithContainers();returnTypeDeduction();autoWithLambdas();autoWithTemplates();autoPitfalls();autoInConcurrency();autoWithModernCpp();configExample();return0;}九、基于范围的for循环C11基于范围的for循环是C11引入的语法糖它极大地简化了容器遍历的代码。#includeiostream#includevector#includemap#includeset#includelist#includearray#includestring#includealgorithm#includeranges// C20// 1. 基本用法voidbasicRangeFor(){std::cout Basic Range-based for Loop std::endl;// 数组遍历intarr[]{1,2,3,4,5};std::coutArray: ;for(intnum:arr){std::coutnum ;}std::coutstd::endl;// vector遍历std::vectorintvec{10,20,30,40,50};std::coutVector: ;for(intnum:vec){std::coutnum ;}std::coutstd::endl;// string遍历std::string strHello;std::coutString characters: ;for(charch:str){std::coutch ;}std::coutstd::endl;}// 2. 使用auto简化voidrangeForWithAuto(){std::cout\n Range-for with auto std::endl;std::vectorstd::stringwords{apple,banana,cherry};// 值拷贝可能昂贵std::coutBy value (copy): ;for(autoword:words){std::coutword ;}std::coutstd::endl;// 常量引用推荐std::coutBy const reference: ;for(constautoword:words){std::coutword ;}std::coutstd::endl;// 引用用于修改std::coutBy reference (modifying): ;for(autoword:words){word[0]toupper(word[0]);std::coutword ;}std::coutstd::endl;}// 3. 自定义类型支持范围for循环classSimpleRange{private:intstart,end;public:SimpleRange(ints,inte):start(s),end(e){}// 必须提供begin()和end()方法int*begin(){returnstart;}constint*begin()const{returnstart;}int*end(){returnend1;}// 注意这里只是示例实际实现更复杂constint*end()const{returnend1;}};voidcustomRangeClass(){std::cout\n Custom Range Class std::endl;// 注意这个示例只是为了演示原理// 实际的自定义范围类需要正确实现迭代器SimpleRangerange(1,5);std::coutCustom range: ;for(intnum:range){std::coutnum ;}std::coutstd::endl;}// 4. 标准库容器遍历voidstandardContainers(){std::cout\n Standard Library Containers std::endl;// liststd::listintlst{1,2,3,4,5};std::coutList: ;for(constautonum:lst){std::coutnum ;}std::coutstd::endl;// setstd::setstd::stringfruits{apple,banana,orange};std::coutSet: ;for(constautofruit:fruits){std::coutfruit ;}std::coutstd::endl;// mapstd::mapint,std::stringstudents{{101,Alice},{102,Bob},{103,Charlie}};std::coutMap (C17前): ;for(constautopair:students){std::cout{pair.first: pair.second} ;}std::coutstd::endl;// C17结构化绑定std::coutMap (C17结构化绑定): ;for(constauto[id,name]:students){std::cout{id: name} ;}std::coutstd::endl;}// 5. 修改元素voidmodifyingElements(){std::cout\n Modifying Elements std::endl;std::vectorintnumbers{1,2,3,4,5};std::coutOriginal: ;for(constautonum:numbers){std::coutnum ;}std::coutstd::endl;// 使用引用修改std::coutSquaring elements: ;for(autonum:numbers){numnum*num;std::coutnum ;}std::coutstd::endl;// 再次查看修改结果std::coutAfter modification: ;for(constautonum:numbers){std::coutnum ;}std::coutstd::endl;}// 6. 遍历多维容器voidmultiDimensional(){std::cout\n Multi-dimensional Containers std::endl;// 二维vectorstd::vectorstd::vectorintmatrix{{1,2,3},{4,5,6},{7,8,9}};std::cout2D vector:std::endl;for(constautorow:matrix){for(constautoelement:row){std::coutelement ;}std::coutstd::endl;}// 数组的数组intarr2D[3][4]{{1,2,3,4},{5,6,7,8},{9,10,11,12}};std::cout\n2D array:std::endl;for(constautorow:arr2D){for(intelement:row){std::coutelement ;}std::coutstd::endl;}}// 7. 使用初始化列表voidwithInitializerList(){std::cout\n With Initializer List std::endl;// 直接遍历初始化列表std::coutDirect initializer list: ;for(intnum:{1,2,3,4,5}){std::coutnum ;}std::coutstd::endl;// 结合算法std::coutWith algorithm (squares): ;for(intnum:{1,2,3,4,5}){std::coutnum*num ;}std::coutstd::endl;}// 8. 性能考虑#includechronovoidperformanceComparison(){std::cout\n Performance Comparison std::endl;constsize_t size1000000;std::vectorintlargeVec(size,1);// 传统for循环autostartstd::chrono::high_resolution_clock::now();longlongsum10;for(size_t i0;ilargeVec.size();i){sum1largeVec[i];}autoendstd::chrono::high_resolution_clock::now();autoduration1std::chrono::duration_caststd::chrono::microseconds(end-start);// 范围for循环startstd::chrono::high_resolution_clock::now();longlongsum20;for(constautonum:largeVec){sum2num;}endstd::chrono::high_resolution_clock::now();autoduration2std::chrono::duration_caststd::chrono::microseconds(end-start);// 迭代器循环startstd::chrono::high_resolution_clock::now();longlongsum30;for(autoitlargeVec.begin();it!largeVec.end();it){sum3*it;}endstd::chrono::high_resolution_clock::now();autoduration3std::chrono::duration_caststd::chrono::microseconds(end-start);std::coutTraditional for loop: duration1.count() microsecondsstd::endl;std::coutRange-based for loop: duration2.count() microsecondsstd::endl;std::coutIterator loop: duration3.count() microsecondsstd::endl;std::coutSums: sum1, sum2, sum3std::endl;}// 9. C20范围库 (ranges)#ifdef__cpp_lib_rangesvoidcpp20Ranges(){std::cout\n C20 Ranges std::endl;std::vectorintnumbers{1,2,3,4,5,6,7,8,9,10};// 使用视图过滤和转换autoevenSquaresnumbers|std::views::filter([](intn){returnn%20;})|std::views::transform([](intn){returnn*n;});std::coutEven numbers squared: ;for(intnum:evenSquares){std::coutnum ;}std::coutstd::endl;// 使用视图取前N个autofirstThreenumbers|std::views::take(3);std::coutFirst three: ;for(intnum:firstThree){std::coutnum ;}std::coutstd::endl;// 反向视图autoreversednumbers|std::views::reverse;std::coutReversed: ;for(intnum:reversed){std::coutnum ;}std::coutstd::endl;}#endif// 10. 实际应用示例classStudent{private:std::string name;std::vectorintgrades;public:Student(std::string n,std::vectorintg):name(n),grades(g){}doubleaverageGrade()const{if(grades.empty())return0.0;doublesum0.0;for(intgrade:grades){sumgrade;}returnsum/grades.size();}voiddisplay()const{std::coutname: ;for(intgrade:grades){std::coutgrade ;}std::cout(Avg: averageGrade())std::endl;}};voidstudentManagement(){std::cout\n Student Management Example std::endl;std::vectorStudentstudents{Student(Alice,{90,85,92}),Student(Bob,{78,82,80}),Student(Charlie,{95,96,94})};std::coutStudent grades:std::endl;for(constautostudent:students){student.display();}// 计算班级平均分doubleclassAverage0.0;for(constautostudent:students){classAveragestudent.averageGrade();}classAverage/students.size();std::cout\nClass average: classAveragestd::endl;// 找出高于平均分的学生std::cout\nStudents above class average:std::endl;for(constautostudent:students){if(student.averageGrade()classAverage){std::coutstudent.averageGrade() ;}}std::coutstd::endl;}// 11. 范围for循环的陷阱voidrangeForPitfalls(){std::cout\n Range-for Pitfalls std::endl;std::vectorintnumbers{1,2,3,4,5};// 陷阱1在遍历时修改容器std::coutBad example (modifying container while iterating):std::endl;// for (auto num : numbers) {// if (num 3) {// numbers.push_back(6); // 可能使迭代器失效// }// std::cout num ;// }// 陷阱2临时容器的遍历std::cout\nTemporary container example:std::endl;for(intnum:std::vectorint{1,2,3}){std::coutnum ;// 临时对象在循环期间有效}std::coutstd::endl;// 陷阱3使用auto处理代理对象std::vectorboolboolVec{true,false,true};std::cout\nProxy object example: ;for(autoval:boolVec){// 使用auto处理代理对象std::coutval ;}std::coutstd::endl;}intmain(){basicRangeFor();rangeForWithAuto();customRangeClass();standardContainers();modifyingElements();multiDimensional();withInitializerList();performanceComparison();#ifdef__cpp_lib_rangescpp20Ranges();#endifstudentManagement();rangeForPitfalls();return0;}十、指针空值nullptrC11nullptr是C11引入的空指针常量解决了传统NULL宏在类型安全和重载解析中的问题。#includeiostream#includetype_traits#includememory// 1. nullptr基本用法voidbasicNullptr(){std::cout Basic nullptr Usage std::endl;// 初始化指针int*ptr1nullptr;double*ptr2nullptr;void*ptr3nullptr;// 检查空指针if(ptr1nullptr){std::coutptr1 is nullptrstd::endl;}if(!ptr2){// 隐式转换为boolstd::coutptr2 is also nullptrstd::endl;}// 与NULL比较int*ptr4NULL;// 传统方式不推荐if(ptr4nullptr){std::coutNULL equals nullptrstd::endl;}}// 2. nullptr vs NULL vs 0voidcompareWithNull(){std::cout\n nullptr vs NULL vs 0 std::endl;// NULL通常是0或(void*)0#ifdefNULLstd::coutNULL is defined as: NULLstd::endl;#endif// 类型信息std::coutType of nullptr: typeid(nullptr).name()std::endl;std::coutType of NULL: typeid(NULL).name()std::endl;std::coutType of 0: typeid(0).name()std::endl;// nullptr的类型是std::nullptr_tstd::nullptr_t null_valuenullptr;std::coutType of null_value: typeid(null_value).name()std::endl;}// 3. 函数重载中的nullptrvoidoverloadedFunction(int*ptr){std::coutCalled with pointer: ptrstd::endl;}voidoverloadedFunction(intnum){std::coutCalled with integer: numstd::endl;}voidoverloadedFunction(std::nullptr_t nullp){std::coutCalled with nullptr_tstd::endl;}voidtestOverloading(){std::cout\n Function Overloading std::endl;// 使用nullptr - 明确调用指针版本overloadedFunction(nullptr);// 调用指针版本或nullptr_t版本// 使用0或NULL - 可能调用整数版本overloadedFunction(0);// 调用整数版本overloadedFunction(NULL);// 可能调用整数版本取决于NULL的定义int*ptrnullptr;overloadedFunction(ptr);// 调用指针版本}// 4. 模板中的nullptrtemplatetypenameTvoidtemplateFunction(T*ptr){if(ptrnullptr){std::coutNull pointer in templatestd::endl;}else{std::coutValid pointer: *ptrstd::endl;}}templatetypenameTvoidcheckPointer(T ptr){ifconstexpr(std::is_pointer_vT){if(ptrnullptr){std::coutPointer is nullstd::endl;}else{std::coutPointer is validstd::endl;}}else{std::coutNot a pointer typestd::endl;}}voidtestWithTemplates(){std::cout\n Templates and nullptr std::endl;intx42;int*ptr1x;int*ptr2nullptr;templateFunction(ptr1);templateFunction(ptr2);checkPointer(ptr1);checkPointer(ptr2);checkPointer(nullptr);checkPointer(10);// 不是指针}// 5. 智能指针中的nullptr#includememoryvoidsmartPointersAndNullptr(){std::cout\n Smart Pointers and nullptr std::endl;// 创建空智能指针std::unique_ptrintup1nullptr;std::shared_ptrintsp1nullptr;std::weak_ptrintwp1;// 检查智能指针是否为空if(!up1){std::coutunique_ptr is emptystd::endl;}if(sp1nullptr){std::coutshared_ptr is nullptrstd::endl;}// 重置为nullptrautosp2std::make_sharedint(42);std::coutsp2 use_count: sp2.use_count()std::endl;sp2nullptr;// 释放资源if(sp2nullptr){std::coutsp2 reset to nullptrstd::endl;}// 使用reset方法autoup2std::make_uniqueint(100);up2.reset();// 等同于 up2 nullptrif(!up2){std::coutup2 has been resetstd::endl;}}// 6. nullptr在类中的应用classResource{private:int*data;public:Resource():data(nullptr){}// 使用nullptr初始化explicitResource(intvalue){datanewint(value);}~Resource(){deletedata;datanullptr;// 防止悬垂指针}// 禁用拷贝Resource(constResource)delete;Resourceoperator(constResource)delete;// 启用移动Resource(Resourceother)noexcept:data(other.data){other.datanullptr;}Resourceoperator(Resourceother)noexcept{if(this!other){deletedata;dataother.data;other.datanullptr;}return*this;}boolisValid()const{returndata!nullptr;}intgetValue()const{if(data){return*data;}throwstd::runtime_error(Resource is empty);}};voidclassExample(){std::cout\n Class Example std::endl;Resource res1;// 空资源Resourceres2(42);// 有值资源std::coutres1 is valid: (res1.isValid()?true:false)std::endl;std::coutres2 is valid: (res2.isValid()?true:false)std::endl;try{std::coutres2 value: res2.getValue()std::endl;// std::cout res1 value: res1.getValue() std::endl; // 抛出异常}catch(conststd::exceptione){std::coutException: e.what()std::endl;}// 移动语义Resource res3std::move(res2);std::coutAfter move:std::endl;std::coutres2 is valid: (res2.isValid()?true:false)std::endl;std::coutres3 is valid: (res3.isValid()?true:false)std::endl;}// 7. nullptr与类型安全voidtypeSafety(){std::cout\n Type Safety std::endl;// nullptr是类型安全的int*ipnullptr;double*dpnullptr;// 不能将nullptr赋值给非指针类型// int i nullptr; // 错误// bool b nullptr; // 错误C11中但在C中nullptr可以转换为bool false// 但可以这样boolb1(ipnullptr);// trueboolb2ip;// false隐式转换std::coutb1: b1std::endl;std::coutb2: b2std::endl;// nullptr与其他指针类型的比较void*vpnullptr;if(ipvp){// 可以比较std::coutint* and void* can both be nullptrstd::endl;}}// 8. 实际应用工厂模式classProduct{public:virtual~Product()default;virtualvoiduse()0;};classConcreteProductA:publicProduct{public:voiduse()override{std::coutUsing Product Astd::endl;}};classConcreteProductB:publicProduct{public:voiduse()override{std::coutUsing Product Bstd::endl;}};classFactory{public:staticstd::unique_ptrProductcreateProduct(conststd::stringtype){if(typeA){returnstd::make_uniqueConcreteProductA();}elseif(typeB){returnstd::make_uniqueConcreteProductB();}returnnullptr;// 无法创建时返回nullptr}};voidfactoryPatternExample(){std::cout\n Factory Pattern Example std::endl;autoproduct1Factory::createProduct(A);autoproduct2Factory::createProduct(B);autoproduct3Factory::createProduct(C);// 无效类型if(product1){product1-use();}if(product2){product2-use();}if(!product3){std::coutFailed to create product Cstd::endl;}}// 9. nullptr与完美转发templatetypenameTvoidprocessValue(Tvalue){std::coutProcessing value...std::endl;}templatetypenameTvoidprocessPointer(T*ptr){if(ptr){std::coutPointer value: *ptrstd::endl;}else{std::coutNull pointerstd::endl;}}voidperfectForwardingExample(){std::cout\n Perfect Forwarding with nullptr std::endl;intx42;int*ptrx;// 完美转发nullptrprocessValue(nullptr);// T被推导为std::nullptr_t// 转发指针processValue(ptr);// T被推导为int*processValue(nullptr);// T被推导为std::nullptr_t// 明确调用指针版本processPointer(ptr);processPointer(nullptr);}// 10. C17的optional与nullptr#includeoptionalvoidoptionalExample(){std::cout\n std::optional and nullptr std::endl;std::optionalintmaybeInt;std::optionalstd::stringmaybeStringHello;// optional没有值时的行为类似nullptrif(!maybeInt){std::coutmaybeInt has no valuestd::endl;}if(maybeString){std::coutmaybeString has value: *maybeStringstd::endl;}// 重置optionalmaybeStringstd::nullopt;// 类似于 nullptrif(!maybeString){std::coutmaybeString is now emptystd::endl;}}// 11. 性能考虑voidperformanceConsiderations(){std::cout\n Performance Considerations std::endl;// nullptr在性能上与NULL/0相同// 主要优势是类型安全不是性能constintiterations100000000;autostartstd::chrono::high_resolution_clock::now();for(inti0;iiterations;i){int*p1nullptr;(void)p1;}autoendstd::chrono::high_resolution_clock::now();autoduration1std::chrono::duration_caststd::chrono::milliseconds(end-start);startstd::chrono::high_resolution_clock::now();for(inti0;iiterations;i){int*p2NULL;(void)p2;}endstd::chrono::high_resolution_clock::now();autoduration2std::chrono::duration_caststd::chrono::milliseconds(end-start);startstd::chrono::high_resolution_clock::now();for(inti0;iiterations;i){int*p30;(void)p3;}endstd::chrono::high_resolution_clock::now();autoduration3std::chrono::duration_caststd::chrono::milliseconds(end-start);std::coutnullptr: duration1.count()msstd::endl;std::coutNULL: duration2.count()msstd::endl;std::cout0: duration3.count()msstd::endl;}// 12. 最佳实践voidbestPractices(){std::cout\n Best Practices std::endl;// 1. 总是使用nullptr而不是NULL或0int*goodPtrnullptr;// int* badPtr NULL; // 避免// int* worsePtr 0; // 避免// 2. 在检查指针时使用显式比较if(goodPtrnullptr){// 清晰std::coutPointer is nullstd::endl;}if(!goodPtr){// 也可以但可能不够清晰std::coutPointer is null (implicit)std::endl;}// 3. 释放后立即设为nullptrint*dynamicPtrnewint(42);deletedynamicPtr;dynamicPtrnullptr;// 防止悬垂指针// 4. 在函数参数中使用nullptr作为默认值autoconfigure[](int*optionnullptr){if(option){*option100;}};// 5. 使用智能指针避免手动nullptr检查autosmartPtrstd::make_uniqueint(42);if(smartPtr){// 仍然可以检查但不是必须的std::coutSmart pointer has value: *smartPtrstd::endl;}}intmain(){basicNullptr();compareWithNull();testOverloading();testWithTemplates();smartPointersAndNullptr();classExample();typeSafety();factoryPatternExample();perfectForwardingExample();optionalExample();performanceConsiderations();bestPractices();return0;}总结通过本文的详细讲解和丰富的代码示例我们已经系统地学习了C的入门核心概念和现代特性。让我们回顾一下重点核心收获C关键字理解了63个关键字的分类和基本用途这是掌握C语法的基础。命名空间学会了如何组织代码、避免命名冲突理解了命名空间的各种用法和最佳实践。输入输出系统掌握了C强大的流式I/O包括格式化输出、文件操作和字符串流处理。缺省参数了解了如何设计灵活的函数接口通过合理的默认值减少代码重复。函数重载掌握了通过参数列表区分同名函数的技巧理解了名字修饰的实现原理。引用深入理解了引用作为别名的本质掌握了左值引用、右值引用和完美转发。内联函数学会了如何通过内联优化小型函数理解了内联的适用场景和限制。auto关键字掌握了类型自动推导使代码更简洁配合现代C特性更加强大。基于范围的for循环学会了简化容器遍历的新语法提高了代码可读性。nullptr理解了类型安全的空指针解决了传统NULL的歧义问题。现代C编程建议拥抱现代特性尽可能使用C11及更高版本的特性它们让代码更安全、高效。类型安全优先使用智能指针、引用和nullptr避免原始指针的滥用。资源管理遵循RAII原则确保资源的正确获取和释放。代码简洁性合理使用auto、范围for循环等特性但不要过度使用影响可读性。性能意识理解内联、移动语义等特性对性能的影响但不要过早优化。学习路径建议对于C初学者建议按照以下路径继续深入学习面向对象编程深入学习类、继承、多态等面向对象特性。模板编程掌握函数模板和类模板理解泛型编程。标准库系统学习STL容器、算法和迭代器。高级主题研究异常处理、多线程、移动语义等高级特性。现代C学习C14/17/20的新特性如概念、协程等。C是一门博大精深的语言学习曲线较陡但掌握它将为你打开系统编程、游戏开发、高性能计算等领域的大门。坚持实践、阅读优秀代码、参与开源项目是提升C技能的最佳途径。记住编程不仅是学习语法更是培养解决问题和设计系统的能力。C为你提供了强大的工具如何使用它们创造价值取决于你的智慧和努力。祝你在C的学习之旅中不断进步