#define _CRT_SECURE_NO_WARNINGS 1 
 #include<stdio.h>
 //在某一循环里,想要准确调试某一次,(如500次循环的299次)用
 //设置断点+右击鼠标条件i==299+F5
 //实例
 // 求1!+2!+....+n!
 //int main()
 //{
 //    int n = 0;
 //    scanf("%d", &n);//scanf的%d后面不能加\n
 //    int i = 0;
 //    int ret = 1;
 //    int j = 0;
 //    int sum = 0;
 //    for (j = 1; j <= n; j++)
 //    {
 //        ret = 1;
 //        for (i = 1; i <= j; i++)
 //        {
 //            ret*= i;
 //        }
 //        sum  += ret;
 //    }
 //    printf("%d\n", sum);
 //    return 0;
 //}
 //for循环   产生1~n的数字
 // 
 //for(i=1;i<=n;i++)
 //{
 //ret = *i;        产生的是n的阶乘
 //}
 // 
 //for (j = i; i <= j; j++)
 //{
 //    for (i = 1; i <= j; i++)
 //    {
 //        ret = *i;    产生的是1+...+n的阶乘
 //    }
 //    sum = +ret;
 //}
//int main()
 //{
 //    int i = 0;
 //    int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
 //    for (i = 0; i <= 12; i++)
 //    {
 //        arr[i] = 0;
 //        printf("hehe\n");//hehe可能死循环,因为数组随着下标的增长地址由低到高,,,,
 //        //栈区内存使用时是先高地址后低地址,i = 0; 先被创建(相比于arr[10],在高地址,,,,,
 //        //但是数组arr[10]一直向上非法占用空间(越界),总有一次使用到i的地址,非法修改i的值,使i重新变为0
 //        //陷入死循环,vs2022没这个可能(因为比较只能,直接报错)
 //        //每个编译器陷入死循环的条件不一样,中间(非法越境)所需要空间不一样
 //    }
 //    return 0;
 //}
 //预防发生错误
 //通过编码的技巧,减少.降低错误
 //模拟实现strcpy(字符串拷贝)
 //#include<string.h>
 //void my_strcpy(char*dest,char*src)//dest和src名字是自己随便起的,对应arr1和arr2的首元素的地址
 //{
 //    while (src != '\n')
 //    {
 //        *dest++ = *src++;
 //    }//没拷贝\0,需要把src的\0也放在dest中,否则dest无法停止(无\0)
 //    *dest = *src;
 //}
 //进阶版
 //void my_strcpy(char* dest, char* src)//dest和src名字是自己随便起的,对应arr1和arr2的首元素的地址
 //{
 //    while (*dest++ = *src++)
 //        //先引用,后++    src里面的h,解引用并放在dest的第一个地址里,然后++,++后src的第二个e解引用.....
 //        //'\0'的SCII值为0,0为假,不满足while循环,停下来 
 //    {
 //        ;
 //    }
 //}
 //再次进阶版(assert考虑空指针的情况)
 //arr2如果是空指针,空指针不能解引用操作
 //#include<assert.h>
 //void my_strcpy(char* dest, const char* src)//dest和src名字是自己随便起的,对应arr1和arr2的首元素的地址
 //{                                       //const作用:使const后面值不能被修改,修改就报错
 //    assert(src!=NULL);//断言----如果不满足,报错(错误信息在哪一行)        //当判断条件用!!!
 //    assert(dest!= NULL);
 //    while (*dest++ = *src++)
 //        //先引用,后++    src里面的h,解引用并放在dest的第一个地址里,然后++,++后src的第二个e解引用.....
 //        //'\0'的SCII值为0,0为假,不满足while循环,停下来 
 //    {
 //        ;
 //    }
 //}
 //int main()
 //{
 //    char arr1[20] = "xxxxxxxxxx";//20字符的空间
 //    char arr2[] = "hello";//5字符的空间
 //    //strcpy(arr1,arr2);//strcpy(arr1,arr2)是字符串拷贝
 //    my_strcpy(arr1, arr2);//arr1为起始代码,arr2为源代码
 //
 //    printf("%s\n%s\n", arr1,arr2);
 //    return 0;
 //}
//const作用:可以直接报错,不执行
 //const作用实例
 //int main()
 //{ 
 // int num = 10;
 //    int* pa = #
 //    *pa = 20;
 //    printf("%d\n", num);//打印结果为20
 //    return 0;
 //}
 //改为
    //锁1:::const int num = 10;//const修饰变量为常变量,不能通过num=20;被修改,但是可以通过地址修改,如int* pa = #依旧正确
     //锁2:int conts * pa = #//const修饰指针变量时,如果放在*左边,修饰的是*p,表示指针指向的内存,不能通过*pa=20;被修改
            //但是锁死的是*pa,而不是pa,还可以给pa赋值,如int n=100;p=&n;还可以给pa赋值,再次修改
     //锁3:int*const pa=#//报错的是pa,即pa锁死了,改不了,*pa能被改(修饰指针变量p,表示指针变量不能被改变,但是指针指向的内容可以改变)
 //右边锁死地址,左边锁死内容
 // 
 //int        *         pa       (原来)
 //int const  *         pa             *pa=0;不能发生   但是pa=&n;n=100;可以发生(通过n改pa,使之改num正确)
 // int       *  const  pa    *pa=0可以发生,但是pa = &n;不能发生(const修饰的是pa本身,不修饰指针*pa,所以不能改num)
 //int const  *  const  pa    *pa=0; pa=&n;都不能发生









