zoukankan      html  css  js  c++  java
  • c语言提高学习笔记——02-c提高03day

    在学习c语言提高总结了笔记,并分享出来。有问题请及时联系博主:Alliswell_WP,转载请注明出处。

    02-c提高03day

    目录:
    1、堆分配内存API
    2、sscanf
    3、练习:查找子串
    4、一级指针易错点
    (1)越界
    (2)指针叠加会不断改变指针指向
    (3)返回局部变量地址
    (4)同一块内存释放多次
    5、const使用
    6、指针的指针(二级指针)
    (1)二级指针基本概念
    (2)二级指针做形参输出特性
     (3)二级指针做形参输入特性
    (4)二级指针练习
    7、位运算
    (1)位逻辑运算符
    1)按位取反~
    2)位与(AND):&
    3)位或(OR):|
    4)位异或:^
    (2)移位运算符
    1)左移<<
    2)右移
    3)用法:移位运算符

    1、堆分配内存API:

     1 #include<stdlib.h>
     2 void *calloc(size_t nmemb,size_t size);
     3 功能:
     4     在内存动态存储区中分配nmemb块长度为size字节的连续区域。calloc自动将分配的内存置0 5 参数:
     6     nmemb:所需内存单元数量
     7     size:每个内存单元的大小(单位:字节)
     8 返回值:
     9     成功:分配空间的起始地址
    10     失败:NULL
     1 #include<stdlib.h>
     2 void *realloc(void *ptr,size_t size);
     3 功能:
     4     重新分配用malloc或者calloc函数在堆中分配内存空间的大小。realloc不会自动清理增加的内存,需要手动清理,如果指定的地址后面有连续的空间,那么就会在已有地址基础上增加内存,如果指定的地址后面没有空间,那么realloc会重新分配新的连续内存,把旧内存的值拷贝到新内存,同时释放旧内存。
     5 参数:
     6    ptr:为之前用malloc或者calloc分配的内存地址,如果此参数等于NULL,那么和realloc与malloc功能一致
     7    size:为重新分配内存的大小,单位:字节
     8 返回值:
     9     成功:新分配的堆内存地址
    10     失败:NULL

    示例代码

     1 void test01(){
     2   int* pl=calloc(10,sizeof(int));//开辟了40个字节,并赋值为0
     3   if(pl==NULL){
     4     return 5   }
     6   for(int i=0;i<10;i++){
     7     pl[i]=i+1 8   }
     9   for(int i=0;i<10;i++){
    10     printf("%d",pl[i]);
    11   }
    12   printf("
    ");
        if(p1 != NULL)
        {
          free(p1);
          p1 = NULL;
        } 13    14 } 15 16 void test02(){ 17   int* pl=calloc(10,sizeof(int));//开辟了40个字节,并赋值为0 18   if(pl==NULL){ 19     return20   } 21   for(int i=0;i<10;i++){ 22     pl[i]=i+123   } 24   //申请空间,如果较小,后边增加返回的p2等于p1如果扩展比较大,重新申请(p2不等于p1),且把之前的数据拷贝至新分配的空间 25   int* p2=realloc(pl,15* sizeof(int)); 26   if(p2==NULL){ 27     return28   } 29   printf("%d ",pl); 30   printf("%d ",p2); 31 32   //打印 33   for(int i=0;i<15;i++){ 34     printf("%d",p2[i]); 35   } 36   printf(" "); 37 38   //重新赋值 39   for(int i=0;i<15;i++){ 40     p2[i]=i+1; 41   } 42 43   //再次打印 44   for(int i=0;i<15;i++){ 45     printf("%d",p2[i]); 46   printf(" "); 47   free(p2); 48 }

    说明:calloc、realloc和sprintf类似,都是申请空间放入数据,sprintf把格式化后的结果放在显示器,calloc、realloc放在内存。

    2、sscanf

     1 #include<stdio.h>
     2 int sscanf(const char *str,const char *format,...);
     3 功能:
     4     从str指定的字符串读取数据,并根据参数format字符串来转换并格式化数据。
     5 参数:
     6     str:指定的字符串首地址
     7     format:字符串格式,用法和scanf()一样
     8 返回值:
     9     成功:实际读取的字符个数
    10     失败:-1

     练习:

     1 #define _CRT_SECURE_NO_WARNINGS
     2 #include<stdio.h>
     3 #include<string.h>
     4 #include<stdlib.h>
     5 
     6 //%*s或%*d 跳过数据
     7 void test01()
     8 {
     9 #if 0
    10     char* str = "12345abcde";
    11     char buf[1024] = { 0 };
    12     sscanf(str, "%*d%s", buf);//跳过数字,剩余字符串
    13     printf("buf:%s
    ", buf);
    14 #else
    15     //忽略字符串到空格或者	
    16     char* str = "12345	abcde";
    17     char buf[1024] = { 0 };
    18     sscanf(str, "%*s%s", buf);//跳过数字,剩余字符串
    19     printf("buf:%s
    ", buf);
    20 #endif    
    21     
    22 }
    23 
    24 //%[width]s读指定宽度的数据
    25 void test02()
    26 {
    27     char* str = "12345abcde";
    28     char buf[1024] = { 0 };
    29     sscanf(str, "%6s", buf);//指定6个字符,12345a
    30     printf("buf:%s
    ", buf);
    31 }
    32 //%[a-z]匹配a到z中任意字符(尽可能多的匹配)
    33 void test03()
    34 {
    35     char* str = "12345abcde";
    36     char buf[1024] = { 0 };
    37     sscanf(str, "%*d%[a-c]", buf);//%[a-c]从第一个开始匹配,有不匹配的,直接结束,所以加入忽略数字
    38     printf("buf:%s
    ", buf);
    39 }
    40 //%[aBc]匹配a、B、c中一员,贪婪性
    41 void test04()
    42 {
    43     char* str = "aABbcde";
    44     char buf[1024] = { 0 };
    45     sscanf(str, %[aAb]", buf);//%[Ab]从第一个开始匹配,有不匹配的,直接结束,所以为aA
    46     printf("buf:%s
    ", buf);
    47 }
    48 //%[^a]匹配非a的任意字符,贪婪性
    49 void test05()
    50 {
    51     char* str = "aABbcde";
    52     char buf[1024] = { 0 };
    53     sscanf(str, %[^c]", buf);//%[^c]从第一个开始匹配,有不匹配的,直接结束,所以为aABb
    54     printf("buf:%s
    ", buf);
    55 }
    56 //%[^a-z]表示读取除a-z以外的所有字符
    57 void test06()
    58 {
    59     char* str = "aABbcde12345";
    60     char buf[1024] = { 0 };
    61     sscanf(str, %[^a-z]", buf);//%[^a-z]从第一个开始匹配,有不匹配的,直接结束,所以为aABbcde
    62     printf("buf:%s
    ", buf);
    63 }
    64 //深入理解,分别提取IP各个字符
    65 void test07()
    66 {
    67     char* ip = "127.0.0.1";
    68     int num1 = 0, num2 = 2, num3 = 0, num4 = 0;
    69     sscanf(ip, "%d.%d.%d.%d", &num1, &num2, &num3, &num4);
    70     printf("num1:%d
    ", num1);
    71     printf("num2:%d
    ", num2);
    72     printf("num3:%d
    ", num3);
    73     printf("num4:%d
    ", num4);
    74 }
    75 //深入理解,提取#和@中间的字符
    76 void test08()
    77 {
    78     char* str = "abcde#12uiop@0plju";
    79     char buf[1024] = {0};
    80     sscanf(str, "%*[^#]#%[^@]", buf);
    81     printf("buf:%s
    ", buf);
    82 }
    83 
    84 
    85 int main(){
    86 
    87     test01();
    88     
    89     system("pause");
    90     return EXIT_SUCCESS;
    91 }

    3、练习:查找子串

     

     1 #define _CRT_SECURE_NO_WARNINGS
     2 #include<stdio.h>
     3 #include<string.h>
     4 #include<stdlib.h>
     5 
     6 //查找子串第一次出现的位置
     7 char* myStrStr(const char* str, const char* substr)
     8 {
     9     const char* mystr = str;
    10     const char* mysub = substr;
    11     
    12     while(*mystr != '')
    13     {
    14         if(*mystr != *mysub)
    15         {
    16             ++mystr;
    17             continue;//找到相同的首个字符,才执行下边的比较
    18         }
    19         //临时指针变量
    20         const char* temp_mystr = mystr;
    21         const char* temp_mysub = mysub;
    22         //比较子串
    23         while(*temp_mysub != '')
    24         {
    25             if(*temp_mystr != *temp_mysub)
    26             {
    27                 ++mystr;
    28                 break;//如果不匹配,退出本次比较(退出本层while),mystr加1开始下轮比较
    29             }
    30             ++temp_mysub;
    31             ++temp_mystr;
    32         }
    33         //说明匹配成功
    34         if(*temp_mysub == '')
    35         {
    36             return (char*)mystr;
    37         }
    38         
    39         
    40     }
    41 }
    42 
    43 void test()
    44 {
    45     char* str = "abcdefg";
    46     char* sub = "de";
    47     char* pos = myStrStr(str, sub);
    48     printf("pos = %s
    ", pos);
    49 }
    50 
    51 int main(){
    52 
    53     test();
    54     
    55     system("pause");
    56     return EXIT_SUCCESS;
    57 }

    实现了查找子串,但还未实现删除后拼接。

    C break——参看:https://www.runoob.com/cprogramming/c-break-statement.html

    4、一级指针易错点
    (1)越界

    1 void test(){
    2     char buf[3]="abc"; //有问题,''还有一个字节
    3     printf("buf:%s
    ",buf);
    4 }

    (2)指针叠加会不断改变指针指向

     1 void test(){
     2     char* p=(char*)malloc(50);
     3     char buf[]="abcdef";
     4     int n=strlen(buf);
     5     int i=0;
     6 
     7     for(i=0;i<n;i++)
     8     {
     9         *p=buf[i];
    10         p++;//修改原指针指向,修改原指针的首地址!free会出问题
    11     }
    12     free(p);
    13 }

    (3)返回局部变量地址

    1 char *get_str()
    2 {
    3     char str[]="abcdedsgads"//栈区,子函数运行完,就释放,不能返回!
    4     printf("[get_str]str=%s
    ",str);
    5     return str;
    6 }

    (4)同一块内存释放多次

     1 void test(){
     2     char* p=NULL;
     3     p=(char*)malloc(50);
     4     strcpy(p,"abcdef");
     5     if(p!=NULL)
     6     {
     7         //free()函数的功能只是告诉系统p指向的内存可以回收了
     8         //就是说,p指向的内存使用权交还给系统
     9         //但是,p的值还是原来的值(野指针),p还是指向原来的内存
    10         free(p):
    11     }
    12     if(p!=NULL)
    13     {
    14         free(p):
    15     }
    16 }

     5、const使用

     1 #define _CRT_SECURE_NO_WARNINGS
     2 #include<stdio.h>
     3 #include<string.h>
     4 #include<stdlib.h>
     5 
     6 struct Person
     7 {
     8     char name[64];
     9     int age;
    10     int ID;
    11     double score;
    12 };
    13 
    14 void PrintPerson(struct Person person)
    15 {
    16     printf("Name:%s Age:%d ID:%d Score:%f
    ",person.name, person.age, person.ID, person.score);
    17 }
    18 
    19 void test()
    20 {
    21     struct Person person = {"Trump", 30, 250, 59.9};
    22     PrintPerson(person);
    23 }
    24 
    25 int main(){
    26 
    27     test();
    28     
    29     system("pause");
    30     return EXIT_SUCCESS;
    31 }

    代码分析:每次打印时候(调用PrintPerson函数)都要拷贝64+4+4+8=80个字节,特别浪费内存。所以考虑使用指针,然而只需要打印,为避免更改数据,使用const。

    改进代码如下:

     1 #define _CRT_SECURE_NO_WARNINGS
     2 #include<stdio.h>
     3 #include<string.h>
     4 #include<stdlib.h>
     5 
     6 struct Person
     7 {
     8     char name[64];
     9     int age;
    10     int ID;
    11     double score;
    12 };
    13 
    14 //规避地址传递的副作用(在使用对象指针的情况下,有可能意外修改数据)
    15 void PrintPerson(const struct Person* person)
    16 {
    17     //person->ID = 128;//增加const后不可修改,修改会报错
    18     printf("Name:%s Age:%d ID:%d Score:%f
    ",person->name, person->age, person->ID, person->score);
    19 }
    20 
    21 void test()
    22 {
    23     struct Person person = {"Trump", 30, 250, 59.9};
    24     PrintPerson(&person);
    25 }
    26 
    27 int main(){
    28 
    29     test();
    30     
    31     system("pause");
    32     return EXIT_SUCCESS;
    33 }

    6、指针的指针(二级指针)

    (1)二级指针基本概念

    1 int a = 12;
    2 int *b = &a;

    假定我们又有了第3个变量,名叫c,并用下面这条语句对它

    1 c = &b;

    问题是:c的类型是什么?显然它是一个指针,但它所指向的是什么?变量b是一个“指向整型的指针”,所以任何指向b的类型必须是指向“指向整型的指针"的指针,更通俗地说,是一个指针的指针。

    它合法吗?是的!指针变量和其他变量一样,占据内存中某个特定的位置,所以用&操作符取得它的地址是合法的。

    那么这个变量的声明是怎样的声明的呢?

    1 int **c=&b;

    那么这个**c如何理解呢?*操作符具有从右想做的结合性,所以这个表达式相当于*(*c),我们从里向外逐层求职。*c访问c所指向的位置,我们知道这是变量b.第二个间接访问操作符访问这个位置所指向的地址,也就是变量a.指针的指针并不难懂,只需要留心所有箭头,如果表达式中出现了间接访问操作符,你就要随箭头访问它所指向的位置。

    (2)二级指针做形参输出特性

    二级指针做形参输出特性指由被调函数分配内存。

     1 #define _CRT_SECURE_NO_WARNINGS
     2 #include<stdio.h>
     3 #include<string.h>
     4 #include<stdlib.h>
     5 
     6 //被调函数分配内存,主调函数使用
     7 void allocateSpace(int** temp)//使用二级指针的目的是为了修改一级指针的值
     8 {
     9     int* arr = malloc(sizeof(int)* 10);
    10     for(int i = 0; i < 10; ++i)
    11     {
    12         arr[i] = i + 1;
    13     }
    14     //指针间接赋值
    15     *temp = arr;
    16 }
    17 
    18 void printArray(int* arr, int len)
    19 {
    20     for(i = 0; i < len; ++i)
    21     {
    22         printf("%d", arr[i]);
    23     }
    24 }
    25 #if 0
    26 void freeSpace(void* arr)
    27 {
    28     if(arr == NULL)
    29     {
    30         return;
    31     }
    32     free(arr);
    33     arr = NULL;
    34 }
    35 #else
    36 void freeSpace(int** arr)
    37 {
    38     if(arr == NULL)
    39     {
    40         return;
    41     }
    42     if(*arr != NULL)
    43     {
    44         free(*arr);
    45         *arr = NULL;
    46         arr = NULL;
    47     }
    48 }
    49 #endif
    50 
    51 void test()
    52 {
    53     int* pArray = NULL;
    54     allocateSpace(&pArray);//本来一级,取完地址二级
    55     printArray(pArray, 10);//pArray为int*类型,&pArray为int**类型
    56 #if 0
    57     freeSpace(pArray);
    58     pArray = NULL;
    59 #esle
    60     freeSpace(&pArray);
    61     if(pArray == NULL)
    62     {
    63         printf("pArray被置空!");
    64     }
    65 #endif
    66 }
    67 
    68 int main(){
    69 
    70     test();
    71     
    72     system("pause");
    73     return EXIT_SUCCESS;
    74 }

     (3)二级指针做形参输入特性

    二级指针做形参输入特性指由主调函数分配内存。

    练习1:堆上开辟空间,指向栈上的空间

    内存模型图如下:

     

     1 //打印数组
     2 void print array(int **arr,int n){
     3     for(int i=0;i<n;i ++){
     4     printf("%d",*(arr[i]));
     5     printf("
    ");
     6 }
     7 //二级指针输入特性(由主调函数分配内存)
     8 void test(){
     9     int al=10;//栈上分配数据空间
    10     int a2=20;
    11     int a3=30;
    12     int a4=40;
    13     int a5=50;
    14 
    15     int n=5;
    16     int** arr=(int **)malloc(sizeof(int *)*n);//堆上分配指针数组
    17 
    18     arr[0]=&al;//*(arr + 0) = &a1;
    19     arr[1]=&a2;//*(arr + 1) = &a2;
    20     arr[2]=&a3;//*(arr + 2) = &a3;
    21     arr[3]=&a4;//*(arr + 3) = &a4;
    22     arr[4]=&a5;//*(arr + 4) = &a5;
    23 
    24     print_array(arr,n);
        if(arr != NULL)
    25   { 26   free(arr);
          arr = NULL;
    27    } 28 arr=NULL; 29 }

    练习2:栈上开辟空间,指向堆上的空间

    内存模型图如下:

     1 #define _CRT_SECURE_NO_WARNINGS
     2 #include<stdio.h>
     3 #include<string.h>
     4 #include<stdlib.h>
     5 
     6 void print array(int **arr,int n){
     7     for(int i=0;i<n;++i){
     8     printf("%d",*(arr[i]));
     9     printf("
    ");
    10 }
    11 
    12 
    13 void test02()
    14 {
    15     int* pArray[5];//栈上分配内存
    16     
    17     for(int i = 0; i < 5; ++i)
    18     {
    19         pArray[i] = malloc(4);//堆上分配内存
    20         *(pArray[i]) = 100 + i;
    21     }
    22     printArray(pArray, 5);
    23     //释放堆内存
    24     for(int i = 0; i < 5; ++i)
    25     {
    26         if(pArray[i] != NULL)
    27         {
    28             free(pArray[i]);
    29             pArray[i] = NULL;
    30         }
    31     }
    32 }
    33 
    34 int main(){
    35 
    36     test02();
    37     
    38     system("pause");
    39     return EXIT_SUCCESS;
    40 }

    (4)二级指针练习

    读取文件(text.txt)内容

    1 //text.txt
    2 aaaaaaaaaaaaaaaaaa
    3 bbbbbbbbbbbbbbbbbbbbbbbbbb
    4 cccccccccccc
    5 ddd
    6 eeeeeeeeeeeeeeeee
    7 ffffffffffffffffffffffffffff

    内存模型图如下:

      1 #define _CRT_SECURE_NO_WARNINGS
      2 #include<stdio.h>
      3 #include<string.h>
      4 #include<stdlib.h>
      5 
      6 //获得文件行数
      7 int getFileLines(FILE* file)
      8 {
      9     if(NULL == file)
     10     {
     11         return -1;
     12     }
     13     char buf[1024] = {0};
     14     int lines = 0;
     15     
     16     while(fgets(buf, 1024, file)!=NULL)
     17     {
     18         ++lines;
     19     }
     20     //恢复文件指针指向文件起始位置
     21     fseek(file, 0, SEEK_SET);
     22         
     23     return lines;
     24 }
     25 
     26 //读取文件数据
     27 void readFileData(FILE* file, int lines, char** contents)
     28 {
     29     if(NULL == file)
     30     {
     31         return;
     32     }
     33     if(NULL == contents)
     34     {
     35         return;
     36     }
     37     if(lines <= 0)
     38     {
     39         return;
     40     }
     41     //创建缓冲区
     42     char buf[1024] = {0};
     43     int index = 0;
     44     while(fgets(buf, 1024, file) != NULL)
     45     {
     46         //printf("buf:%s",buf);
     47         int curLineLen = strlen(buf) + 1;//strlen计算给定字符串的(unsigned int型)长度,不包括''在内
     48         //给当前行分配内存
     49         char* lineContent = malloc(sizeof(char) * curLineLen);
     50         //将行数据拷贝到空间中
     51         strcpy(lineContent, buf);
     52         contents[index++] = lineContent;
     53         memset(buf,0,1024);
     54     }
     55     
     56     
     57     
     58 }
     59 //打印文件内容
     60 void showFileContents(char** contents, int lines)
     61 {
     62     for(int i = 0; i < lines; ++i)
     63     {
     64         printf("%d行:%s",i+1,contents[i]);
     65     }
     66 }
     67 
     68 //释放文件数据内存
     69 void freeFileSpace(char** contents, int lines)
     70 {
     71     for(int i = 0; i < lines; ++i)
     72     {
     73         if(contents[i] != NULL)
     74         {
     75             free(contents[i]);
     76             contents[i] = NULL;
     77         }
     78     }
     79     free(contents);
     80     contents = NULL;
     81 }
     82 
     83 void test()
     84 {
     85     //打开文件
     86     FILE* file = fopen("./text.txt","r");
     87     if(NULL == file)
     88     {
     89         printf("打开文件失败!
    ");
     90         return;
     91     }
     92     //统计文件行数
     93     int lines = 10;
     94     lines = getFileLines(file);
     95     printf("lines:%d
    ",lines);
     96     
     97     char** pContents = malloc(sizeof(char*) * lines);
     98     
     99     //读取文件内容
    100     readFileData(file, lines, pContents);
    101     
    102     //关闭文件
    103     fclose(file);
    104     file = NULL;
    105     
    106     //打印文件内容
    107     showFileContents(pContents, lines);
    108     
    109     //释放文件数据
    110     freeFileSpace(pContents, lines);
    111     
    112 }
    113 
    114 int main(){
    115 
    116     test();
    117     
    118     system("pause");
    119     return EXIT_SUCCESS;
    120 }

    7、位运算

    可以使用C对变量中的个别位进行操作。您可能对人们想这样做的原因感到奇怪。这种能力有时确实是必须的,或者至少是有用的。C提供位的逻辑运算符和移位运算符。在以下例子中,我们将使用二进制计数法写出值,以便您可以了解对位发生的操作。在一个实际程序中,您可以使用一般的形式的整数变量或常量。例如不适用00011001的形式,而写为25或者031或者0x19.在我们的例子中,我们将使用8位数字,从左到右,每位的编号是7到0。

    (1)位逻辑运算符

    4个位运算符用于整型数据,包括char.将这些位运算符成为位运算的原因是它们对每位进行操作,而不影响左右两侧的位。请不要将这些运算符与常规的逻辑运算符(&&、||和!)相混淆,常规的位的逻辑运算符对整个值进行操作。

    1)按位取反~
    一元运算符~将每个1变为0,将每个0变为1,如下面的例子:

    1 ~(10011010)
    2 01100101

    假设a是一个unsigned char,已赋值为2.在二进制中,2是00000010.于是~a的值为11111101或者253。请注意该运算符不会改变a的值,a仍为2。

    unsigned char a=2;//00000010
    unsigned char b=~a;//11111101
    printf("ret=8d
    ",a);//ret=2
    printf("ret=%d
    ",b);//ret=253

    带符号整型的需要注意:int number =2; ~a得到101,而负数采用补码存储,得到-3


    2)位与(AND):&
    二进制运算符&通过对两个操作数逐位进行比较产生一个新值。对于每个位,只有两个操作数的对应位都是1时结果才为1。

    1100100112 &(00111101)
    3 =(00010001

    C也有一个组合的位与-赋值运算符:&=。下面两个将产生相同的效果:

    1 val&=0377
    2 val=val & 0377

    可判断一个数的奇偶性——思路:取出最后一位:(number&1)==0为偶数,否则为奇数

    应用:取出某一位;把某一位清零


    3)位或(OR):|
    二进制运算符通过对两个操作数逐位进行比较产生一个新值。对于每个位,如果其中任意操作数中对应的位为1,那么结果位就为1.

    110010011)
    2 |(00111101)
    3 =(10111111

    C也有组合位或赋值运算符:|=

    1 val |=0377
    2 val=val | 0377

    应用:把某一位置1

    4)位异或:^
    二进制运算符对两个操作数逐位进行比较。对于每个位,如果操作数中的对应位有一个是1(但不是都是1),那么结果是1.如果都是0或者都是1,则结果位0.——类似于做差取绝对值!

    1100100112 ^(001111013 =(10101110

    C也有一个组合的位异或-赋值运算符:^=

    1 val^=0377
    2 val=val ^ 0377

    应用:不需要第三个变量,可交换两个变量。

     

    (2)移位运算符
    现在让我们了解一下C的移位运算符。移位运算符将位向左或向右移动。同样,我们仍将明确地使用二进制形式来说明该机制的工作原理。

    1)左移<<
    左移运算符<<将其左侧操作数的值的每位向左移动,移动的位数由其右侧操作数指定。空出来的位用0填充,并且丢弃移出左侧操作数未端的位。在下面例子中,每位向左移动两个位置。

    1 (10001010)<<2
    200101000

    该操作将产生一个新位置,但是不改变其操作数。

    1 1<<1=22 2<<1=43 4<<1=84 8<<2=32;

    左移一位相当于原值*2.

    2)右移
    右移运算符>>将其左侧的操作数的值每位向右移动,移动的位数由其右侧的操作数指定。丢弃移出左侧操作数有段的位。对于unsigned类型,使用0填充左端空出的位。对于有符号类型,结果依赖于机器。空出的位可能用0填充,或者使用符号(最左端)位的副本填充。

     1 //有符号值
     2 (10001010)>>2
     3 (00100010)//在某些系统上的结果值
     4 
     5 (10001010)>>2
     6 (11100010)//在另一些系统上的解雇
     7 
     8 //无符号值
     910001010)>>2
    1000100010//所有系统上的结果值

    3)用法:移位运算符
    移位运算符能够提供快捷、高效(依赖于硬件)对2的幂的乘法和除法。

     

    参考:

    1)讲义:豆丁网:https://www.docin.com/p-2159552288.html
    道客巴巴:https://www.doc88.com/p-6951788232280.html

    2)C break——参看:https://www.runoob.com/cprogramming/c-break-statement.html

    在学习c语言提高总结了笔记,并分享出来。有问题请及时联系博主:Alliswell_WP,转载请注明出处。

  • 相关阅读:
    bzoj4196: [Noi2015]软件包管理器
    bzoj3083: 遥远的国度
    bzoj4034: [HAOI2015]T2
    2.EXIT_KEY
    AD如何1比1打印
    编程时注意,
    同步事件、异步事件、轮询
    事件位
    挂起进程相关API
    PROCESS_EVENT_POLL事件
  • 原文地址:https://www.cnblogs.com/Alliswell-WP/p/C_ImprovedLearning_03.html
Copyright © 2011-2022 走看看