• 知识点


    转自

    https://blog.csdn.net/qq_37867156/article/details/81837545     关于 0x3f3f3f3f

     https://www.cnblogs.com/qunqun/p/8653806.html     int   long long    unsigned long long 数据范围

    https://blog.csdn.net/qq_34637408/article/details/70877953   二维数组做函数参数 及返回值 

    https://www.cnblogs.com/shuqingstudy/p/4733307.html   c 语言 memcpy 二维数组的复制

    百度百科:左值和右值

    时时勤拂拭

    一,int   long long    unsigned long long

    unsigned   int   0~4294967295   
    int   2147483648~2147483647                    10位  2^31-1
    unsigned long 0~4294967295
    long   2147483648~2147483647
    long long的最大值:9223372036854775807      19位  2^63-1
    long long的最小值:-9223372036854775808
    unsigned long long的最大值:18446744073709551615     20位   2^64-1

    __int64的最大值:9223372036854775807
    __int64的最小值:-9223372036854775808
    unsigned __int64的最大值:18446744073709551615

    二,pi 的定义

     const double pi = acos(-1.0);
    const double pi = 4.0*atan(1.0);
    const double pi = 2*asin(1.0);    //注意定义域

    三,无穷大的定义

    ① 0x3f3f3f3f是一个很有用的数值,它是满足以下两个条件的最大整数。
    1、整数的两倍不超过 0x7f7f7f7f,即int能表示的最大正整数。
    2、整数的每8位(每个字节)都是相同的。
    ② ~0U > > 1 
    ~ 按位求反
    u 作为数字后缀 代表 unsigned 类型变量
    >> 1右移一位
    在32位的情况下,连起来就是 将32位的0取反后 右移一位。
    也就是 01111(31个1)
    也就是 int 的最大值 2147482347
     
    我们在程序设计中经常需要使用 memset(a, val, sizeof (a)) 初始化一个数组a,
    该语句把数值 val(0x00~0xFF)填充到数组a 的每个字节上,所以用memset只能赋值出“每8位都相同”的 int。
     
    当需要把一个数组中的数值初始化成正无穷时,为了避免加法算术上溢出或者繁琐的判断,
    我们经常用 memset(a, 0x3f, sizeof(a)) 给数组赋 0x3f3f3f3f的值来代替。
     
    四,free() 的使用
     double * p = (double*)malloc(sizeof(double*));       // 这步错了
     *p = 4;
    printf("%lf ", *p);
     free(p);
     p = NULL;
     
    虽然 *p 可以打印出来
    但当分配的字节与类型不匹配时,无法释放,会报错
     
    五,~
    1. 所有正整数的按位取反是其本身+1的负数
    2. 所有负整数的按位取反是其本身+1的绝对值
    3. 零的按位取反是 -1(0在数学界既不是正数也不是负数)
     
    六,二维数组
    #define _CRT_SECURE_NO_WARNINGS
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    typedef int(*R)[3];   // 列数固定
    void fun1(int a[][3])
    {
        a[1][3] = 666;
    }
    R fun2(int a[][3])
    {
        a[1][3] = 555;
        return a;
    }
    int main(void)
    {
        int b[3][3] = { 0 };
        
        fun1(b);
        printf("%d
    ", b[1][3]);
        
        memcpy(b, fun2(b), sizeof(fun2(b)));
        printf("%d
    ", b[1][3]);
    
        system("pause");
        return 0;
    }

     那么问题来了,为什么调用第一个函数之后 main 函数的 数组 b 会变?

    其实很简单,其实数组传递的是指针,在函数调用中,它并没有在栈中另开一个数组

    而是通过指针引用 mian 函数中的数组。之前完全没有想到。( ´◔ ‸◔`)

    七,数组的复制与比较

    ① memcmp: 三个参数

     
    比较内存区域buf1和buf2的前count个字节。
     
    #include <string.h>或#include<memory.h>
     
    • 如果返回值 < 0,则表示 str1 小于 str2。
    • 如果返回值 > 0,则表示 str2 小于 str1。
    • 如果返回值 = 0,则表示 str1 等于 str2。 

     ② memcpy void

    参数:  (destin,source,n)

    • destin-- 指向用于存储复制内容的目标数组,类型强制转换为 void* 指针。
    • source-- 指向要复制的数据源,类型强制转换为 void* 指针。
    • n-- 要被复制的字节数。
    功能: 从 source 所指的内存地址的起始位置开始拷贝 n 个字节到目标 destin 所指的内存地址的起始位置中
    返回值:该函数返回一个指向 destin 的指针
     
    八,关于 strlen 的一些问题
    int main(void)
    {
    	char p[] = { 'a','b','c' };
    	printf("%d
    ", strlen(p));
    	printf("%c
    ", *(p + 3));
    
    	
    	system("pause");
    	return 0;
    }
    

      首先,这段代码是可以正常运行的,其中我得到的 strlen(P) 为 15,这里根据大家环境不同,应该有区别

    但明明 p 数组长度为 3,怎么没有报错。大家看一下错误的代码:

    int main(void)
    {
    	char p[] = { 'a','b','c' };
    	//printf("%d
    ", strlen(p));
    	printf("%c
    ", *(p + 3));
    
    	system("pause");
    	return 0;
    }
    

     没有 strlen 就直接报错 了

    我估计是 因为这里没有限制长度,然后 strlen 里面的 循环就扩展了 数组的长度,

    但是,下面这个代码却没有问题:

    int main(void)
    {
    	char p[] = { 'a','b','c' };
    	printf("%d ", *(p + strlen(p) + 10));
    	
    	system("pause");
    	return 0;
    }
    

     搞不明白  ( ‘-ωก̀ )

     九,缩写

    #define mem(a,b) memset(a,b,sizeof(a))
    

      

    十,左值与右值

    按字面意思,通俗地说。以赋值符号 = 为界,= 左边的就是左值,= 右边就是右值。 比如:(1) int b = 3;(2) int a = b;第(2)行代码,a为左值,b为右值。
    更深一层,可以将 L-value 的 L, 理解成 Location,表示定位,地址。将 R-value 的 R 理解成 Read,表示读取数据。现在的计算机数据放在内存。内存有两个很基本的属性:内存地址和内存里面放的数据。想象完全一样的箱子。每个箱子有个编号,用来区分到底是哪个箱子,箱子里面可以放东西。内存地址相当于箱子的编号,内存的数据,相当于箱子里面放的东西。
    变量名编译之后,会映射成内存地址。看看a = b的含义。其实就是 将 "b地址内存里面的数据",放到"a地址内存"中。
     
     
    左值右值基本信息
     
    C/C++语言中可以放在赋值符号左边的变量,即具有对应的可以由用户访问的存储单元,并且能够由用户去改变其值的量。左值表示存储在计算机内存的对象,而不是常量或计算的结果。或者说左值是代表一个内存地址值,并且通过这个内存地址,就可以对内存进行读并且写(主要是能写)操作;这也就是为什么左值可以被赋值的原因了。相对应的还有右值:当一个符号或者常量放在操作符右边的时候,计算机就读取他们的“右值”,也就是其代表的真实值。简单来说就是,左值相当于地址值,右值相当于数据值。右值指的是引用了一个存储在某个内存地址里的数据。
    案例列举
    编辑
    比如: int ia,ib;
    ib=0;
    ia=ib;
    在这里,首先定义ia,ib。然后对ib赋值,此时计算机取ib的左值,也就是这个符号代表的内存位置即内存地址值,计算机取0的右值,也就是数值0;然后给ia赋值为ib,此时取ib的右值给ia的左值;
    所以说,ib的左值、右值是根据他的位置来说的;
    这也算是形式语言的一个有意思之处吧。
     
     
    左值右值翻译:
    L-value中的L指的是Location,表示可寻址。Avalue (computer science)that has an address.
    R-value中的R指的是Read,表示可读。in computer science, a value that does not have an address in a computer language.
    左值和右值是相对于赋值表达式而言的。左值是能出现在赋值表达式左边的表达式。左值表达式可以分为可读写的左值和只读左值。右值是可以出现在赋值表达式右边的表达式,他可以是不占据内存空间的临时量或字面量,可以是不具有写入权的空间实体。如
    int a=3;
    const int b=5;
    a=b+2; //a是左值,b+2是右值
    b=a+2; //错!b是只读的左值但无写入权,不能出现在赋值符号左边
    (a=4)+=28; //a=4是左值表达式,28是右值,+=为赋值操作符
    34=a+2; //错!34是字面量不能做左值
     
    十一,#define 与三目运算符的陷阱
    先上一段代码
    #define _CRT_SECURE_NO_WARNINGS
    #include<stdlib.h>
    #include<stdio.h>  
    int main(void)
    {
    #define MAX(x,y) (x>y)?(x):(y)
    #define MIN(x,y) (x<y)?(x):(y)
    	printf("%d
    ", MIN(3, 4));
    	printf("%d
    ", MIN(11, MAX(3, 4)));
    
    	system("pause");
    }
    

     这个看着没什么问题,但是一运行第二个结果就错了。为什么会这样呢?

    那是因为 #define 只是替换而已 而且 三目运算符 是右结合,即从右向左算的,你连用两个#define,自己一展开就会发现 运算顺序乱了。

    解决方法,只要在前面最外面加一个括号就可以了,保证不会和外界的混淆,代码如下:

    #define _CRT_SECURE_NO_WARNINGS
    #include<stdlib.h>
    #include<stdio.h>  
    int main(void)
    {
    #define MAX(x,y) (x>y?x:y)
    #define MIN(x,y) (x<y?x:y)
    	printf("%d
    ", MIN(3, 4));
    	printf("%d
    ", MIN(11, MAX(3, 4)));
    
    	system("pause");
    }
    
     
     

    ========== ========= ======== ======= ====== ===== ==== === == =

    Do you think, because I am poor, obscure, plain, and little,I am soulless and heartless? 

    You think wrong! 

    I have as much soul as you,  and full as much heart!

    And if God had gifted me with some beauty and much wealth, I should have made it as hard for you to leave me, as it is now for me to leave you.  

    I am not talking to you now through the medium of custom, conventionalities, nor even of mortal flesh; it is my spirit that addresses your spirit,

    just as if both had passed through the grave, and we stood at God's feet, equal, -- as we are!        —— —— Jane Eyre

     
     
  • 相关阅读:
    POI处理Excel工具类
    Mac打开隐藏文件夹
    markdown语法
    U盘分区合并
    数组
    Java插入到mysql数据库显示问号?
    使用vmware打开别人提供好的vmx没反应怎么办?
    求长方形的外接圆
    读取mysql数据库
    excel对列的常用操作
  • 原文地址:https://www.cnblogs.com/asdfknjhu/p/12357013.html
Copyright © 2020-2023  润新知