平常小知识点

    xiaoxiao2022-07-12  154

    本片博客为个人平常总结小知识点

    memset函数while()停止条件自加自减前置后置基本区别重载区别 continue和breakbreakcontinue 数组结果的另类输出

    memset函数

    原型:

    # include <string.h> void *memset(void *s, int c, unsigned long n);

    函数的功能是:将指针变量 s 所指向的前 n 字节的内存单元用一个“整数” c 替换,注意 c 是 int 型。s 是 void* 型的指针变量,所以它可以为任何类型的数据进行初始化。 当然,数组也可以直接进行初始化,但 memset 是对较大的数组或结构体进行清零初始化的最快方法,因为它是直接对内存进行操作的。 这时有人会问:“字符串数组不是最好用’\0’进行初始化吗?那么可以用 memset 给字符串数组进行初始化吗?也就是说参数 c 可以赋值为’\0’吗?” 可以的。虽然参数 c 要求是一个整数,但是整型和字符型是互通的。但是赋值为 ‘\0’ 和 0 是等价的,因为字符 ‘\0’ 在内存中就是 0。所以在 memset 中初始化为 0 也具有结束标志符 ‘\0’ 的作用,所以通常我们就写“0”。 memset 函数的第三个参数 n 的值一般用 sizeof() 获取,这样比较专业。注意,如果是对指针变量所指向的内存单元进行清零初始化,那么一定要先对这个指针变量进行初始化,即一定要先让它指向某个有效的地址。而且用memset给指针变量如p所指向的内存单元进行初始化时,n 千万别写成 sizeof§,这是新手经常会犯的错误。因为 p 是指针变量,不管 p 指向什么类型的变量,sizeof§ 的值都是 4。

    例子:

    # include <stdio.h> # include <string.h> int main(void) { int i; //循环变量 char str[10]; char *p = str; memset(str, 0, sizeof(str)); //只能写sizeof(str), 不能写sizeof(p) for (i=0; i<10; ++i) { printf("%d\x20", str[i]); } printf("\n"); return 0; }

    根据memset函数的不同,输出结果也不同,分为以下几种情况: memset(p, 0, sizeof§); //地址的大小都是4字节 0 0 0 0 -52 -52 -52 -52 -52 -52

    memset(p, 0, sizeof(*p)); //*p表示的是一个字符变量, 只有一字节 0 -52 -52 -52 -52 -52 -52 -52 -52 -52

    memset(p, 0, sizeof(str)); 0 0 0 0 0 0 0 0 0 0

    memset(str, 0, sizeof(str)); 0 0 0 0 0 0 0 0 0 0

    memset(p, 0, 10); //直接写10也行, 但不专业 0 0 0 0 0 0 0 0 0 0

    while()停止条件

    while(n–); while(a!=6,b!=3) while(~scanf("%D%d",&a,&b)); 如果a和b都被成功读入,那么scanf的返回值就是2 如果只有a被成功读入,返回值为1 如果a和b都未被成功读入,返回值为0 如果遇到错误或遇到end of file,返回值为EOF。 此外写成2 == scanf()格式是一种编程风格~防止由于程序员手误写成"="

    自加自减前置后置

    由于自加和自减两种情况差不多,因此我就只讲一种。

    基本区别

    1 int num1 = 1; 2 int num2; 3 // 运行到此处:当前num1=1,num2=0; 4 num2 = ++num1; 5 // 运行到此处:当前num1=2,num2=2;(前加加,num1先加,然后再为num2赋值) 7 num2 = num1++; // 运行到此处:当前num1=2,num2=2; 8 // 运行到此处:当前num1=3,num2=2;(后加加,先为num2赋值,然后num1再加加) ```

    重载区别

    运算符++和—有前置和后置两种形式,如果不区分前置和后置,则使用operator++( )或operator–( )即可;否则,要使用operator++( )或operator–( )来重载前置运算符,使用operator++(int)或operator–(int)来重载后置运算符,调用时,参数int被传递给值0。如下列程序段: (1) 用成员函数的形式来进行重载 如果++为前增量运算符时,重载函数的一般格式为: < type > ClassName :: operator ++ ( ) { //… } 如果++为后增量运算符时,重载函数的一般格式为: < type > ClassName :: operator ++ ( int ) { //… } (2) 非成员函数形式的重载 以++ 为例说明 用友元函数来实现“++”运算符的重载时,前置++运算符的重载的一般格式: friend operator ++ (ClassName & ); 其中,第一个参数是要实现++运算的对象。

    后置++运算符的重载的一般格式: friend operator ++(ClassName &,int); 其中,第一个参数是要实现++运算的对象;而第二个参数除了用于区分是后置运算外,并没有其他意义,故起参数可有可无. 例子:

    #include <iostream> using namespace std; class Complex { private: int a; int b; public: Complex(int a= 0,int b = 0) { this->a = a; this->b =b; } //友元函数实现运算符++的重载 friend Complex& operator++(Complex &c1) ; void printCom(void) { cout<< a << "+" << b << 'i'<< endl; } }; //对前置运算符进行重载 // ++c1 因为最终要得到c1本身函数返回一个引用 这样才能够实现返回引用 Complex& operator++(Complex &c1) { c1.a++; c1.b++; return c1; } int main() { Complex c1(1,2),c2(3,4); Complex c3(0,0); ++c1; ++c1; c1.printCom(); cout << "hello world!" << endl; system("pause"); return 0;} #include <iostream> using namespace std; class Complex { private: int a; int b; public: Complex(int a= 0,int b = 0) { this->a = a; this->b =b; } //友元函数实现运算符前置++的重载 friend Complex& operator++(Complex &c1); //友元函数实现运算符后置++的运算符重载 friend Complex operator++(Complex &c1, int); void printCom(void) { cout<< a << "+" << b << 'i'<< endl; } protected: private: }; //对前置运算符进行重载 // ++c1 因为最终要得到c1本身函数返回一个引用 这样才能够实现返回引用 Complex& operator++(Complex &c1) { c1.a++; c1.b++; return c1; } //后置++的运算符重载 //因为后置++的形式和前置++的一样 因此C++里面提供一个占位符的语法可以使用 //调用的时候C++编译器会自动的调用带有占位符的后置 ++的重载函数 Complex operator++(Complex &c1, int) //返归一个元素 //函数返回值不是函数重载的判断标志 { 原理分析 //return c1; //c1.a++; //c1.b++; Complex tmp = c1; //保证是c1先使用在++ c1.a++; c1.b++; return tmp; } int main() { Complex c1(1,2),c2(3,4); Complex c3(0,0); // //++c1; //++c1; //c1.printCom(); //后置的++ c1++; c1.printCom(); cout << "hello world!" << endl; system("pause"); return 0; }

    continue和break

    break

    用break语句可以使流程跳出switch语句体,也可以用break语句在循环结构终止本层循环体,从而提前结束本层循环。

    使用说明:

    (1)只能在循环体内和switch语句体内使用break;

    (2)当break出现在循环体中的switch语句体内时,起作用只是跳出该switch语句体,并不能终止循环体的执行。若想强行终止循环体的执行,可以在循环体中,但并不在switch语句中设置break语句,满足某种条件则跳出本层循环体。

    continue

    continue语句的作用是跳过本次循环体中余下尚未执行的语句,立即进行下一次的循环条件判定,可以理解为仅结束本次循环。 注意:continue语句并没有使整个循环终止。 扩展资料: 在while和do-while循环中,continue语句使得流程直接跳到循环控制条件的测试部分,然后决定循环是否继续进行。在for循环中,遇到continue后,跳过循环体中余下的语句,而去对for语句中的“表达式3”求值,然后进行“表达式2”的条件测试,最后根据“表达式2”的值来决定for循环是否执行。再循环体内,不论continue是作为何种语句中的成分,都将按上述功能执行,这点与break有所不同。

    //break是结束整个循环体,continue是结束单次循环 比方说:

    while(x++ < 10) { if(x == 3) { break; } printf("%d\r\n", x); }

    结果是输出 1 2 就退出了整个while循环 但是如果使用continue

    while(x++ < 10) { if(x == 3) { continue; } printf("%d\r\n", x); }

    数组结果的另类输出

    #include <iostream> using namespace std; int main() { int array[] = { 10, 20, 30 }; cout << -2 [array]; return 0; }

    output:

    -30

    Explanation:

    -2[array]: this statement is equivalent to -(array[2]). At the zero index 30 is stored hence negation of       30 will be printed due to unary operator (-). -2 [array]:此语句相当于 - (array [2])。在零指数30处存储因此由于一元运算符( - )将打印30的否定。

    结果是:1 2 4 5 6 7 8 9 10 可见他仅仅是不输出3,因为他结束了本次循环 参考:https://blog.csdn.net/andrewgithub/article/details/78761981

    最新回复(0)