评论

收藏

[C++] c语言_Day25_07-26

编程语言 编程语言 发布于:2021-07-26 20:04 | 阅读数:521 | 评论:0

c语言_Day25_07-26
1、实用调试技巧
1、优秀代码技巧
优秀代码:
  • 代码运行正常
  • bug很少
  • 效率高
  • 可读性高
  • 可维护性高
  • 注释清晰
  • 文档齐全
常见的coding技巧:
  • 使用assert
  • 尽量使用const
  • 良好的编码风格
  • 添加必要的注释
  • 避免编码的陷阱
例:
  • 模拟实现strcpy函数
char* my_strcpy(char des[], const char source[])
{
    assert(des != NULL && source != NULL);    // 避免传入空指针导致程序崩溃
    // 获取传入字符串的长度
    int des_len = (int)strlen(des);
    int source_len = (int)strlen(source);
    // 把source指向的字符拷贝至des中
    if (des_len >= source_len)
    {
        for (int i = 0; i < source_len + 1; i++)
        {
            des[i] = source[i];
        }
    }
    else
    {
        for (int i = 0; i < des_len; i++)
        {
            des[i] = source[i];
        }
    }
    return des;
}

int main()
{
    char des[] = "##";
    char source[] = "hello";
    char* p = my_strcpy(des, source);
    printf("%s\n", des);
    printf("%s\n", p);

    return 0;
}
注:const关键字可修饰指针变量,以增加代码的安全性
const int* p 修饰*p:不能通过p改变*p的值
int* const p 修饰p:可以通过p改变*p的值,但不能修改地址
int main()
{
    int num = 10;
    int other = 100;
    const int* p1 = #
    int* const p2 = #
    const int* const p3 = #
    p1 = &other;
    *p2 = other;
    printf("%d %d %d\n", *p1, *p2, *p3); 

    return 0;
}
  • 模拟实现strlen函数:
int my_strlen(const char* str)
{
    assert(str != NULL);
    int p_start = str;
    int p_end = NULL;
    while (*str)
    {
        str++;
    }
    p_end = str;
    return p_end - p_start;
}
2、常见错误
  • 编译性错误:语法错误。根据vs的提示锁定错误
  • 链接性错误:使用未声明变量或函数。应当查明具体的变量或函数,补充定义或引入外部文件
  • 运行时错误:逻辑错误。应借助调试,逐步定位错误
2、数据存储1、数据类型
c语言具有两种类型:内置类型构造类型
内置类型:
char 1字节

short 2字节

int 4字节

long 8字节

long long 8字节

float 4字节

double 8字节
类型的意义:
  • 变量存储的大小
  • 内存空间的存储模式(如整形的存储与浮点型的存储有极大不同)
2、类型的基本归类
  • 整形家族
char :unsigned char / signed char

short :unsigned short / signed short

int :unsigned int / signed int

long :unsigned long / signed long
  • 浮点型家族
float

double
  • 构造类型
数组
结构体
枚举
联合类型
  • 指针类型
  • 空类型(void)

3、整形存储
注:有符号数中的负数原码、反码和补码不同,其余整形三码相同
原码:直接将二进制按正负数的形式翻译成二进制
反码:符号位不变,将原码取反
补码:反码+1
int a = 20;
// 原码:0000 0000 0000 0000 0000 0000 0001 0100    0x00000014
// 反码:0000 0000 0000 0000 0000 0000 0001 0100    0x00000014
// 补码:0000 0000 0000 0000 0000 0000 0001 0100    0x00000014
int b = -10;
// 原码:1000 0000 0000 0000 0000 0000 0000 1010
// 反码:1111 1111 1111 1111 1111 1111 1111 0101
// 补码:1111 1111 1111 1111 1111 1111 1111 0110    0xfffffff6
在计算机中,整形一律通过补码来存储,因为是用补码可以将符号位和数值域统一处理;同时,加法和减法也可以同意处理(CPU只有加法器)。此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件设施
1 - 1 = 1 + (-1)
// 若内存存储为原码:
/* 00000000000000000000000000000001 + 
   10000000000000000000000000000001 = 
   10000000000000000000000000000010(-2)不符合逻辑
*/ 
// 若内存存储为补码:
/* 00000000000000000000000000000001 +
   11111111111111111111111111111111 = 
   00000000000000000000000000000000(0) 符合逻辑
*/
大小端
大端模式:数据的低位保存在内存的高位(字节顺序)
小端模式:数据的低位保存在内存的低位(字节顺序)
/// <summary>
/// 检查系统的存储方式(大小端检测)
/// </summary>
/// <returns>1表示小端,0表示大端</returns>
int check_sys()
{
    int num = 1;
    char* p = (char*)#
    if (*p > *(p + 1))
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

int main()
{
    if (check_sys())
    {
        printf("小端\n");
    }
    else
    {
        printf("大端\n");
    }

    return 0;
}

关注下面的标签,发现更多相似文章