小知识积累

本文探讨了C和C++编程中的多个实用技巧,包括printf的使用细节、位运算符的应用、判断数值特性以及注释去除算法等。此外,还讨论了C与C++之间的差异及其相互调用的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.有关++和printf的应用
printf是从右向左压栈
printf(“%d,%d\n”,ptr,(++ptr));
先是++ptr
从右至左,所以输出的两个值是一样的
*(ptr++)+=123;
那么先是*ptr+=123;
然后是ptr++;

2.
float a = 1.0f;
(int&)a的作用是将浮点数地址开始的sizeof(int)个字节当成int型的数据输出,因此这取决于float型数据在内存中的存储方式而不是经过(int&)a显示的转换结果

但是如果是0那么就是0了

3.

int main()
{
    unsigned int a = 0xFFFFFFF7;
    unsigned char i = (unsigned char)a;
    char* b = (char*)&a;

    printf("%08x ,%08x\n", i, *b);//最小输出宽度是8,输出的是16进制
    return 0;
}

4.有关运算符优先级以及位运算和进制转换

int main()
{
    unsigned  char a = 0xA5;
    unsigned char b = ~a>>4+1;

//  cout << b << endl;
    printf("%d\n", b);
    return 0;
}

5.用一个表达式,判断一个数X是否是2的N次方
!(X&(X-1))

6.位运算符的数字交换方法
a=a^b;
b=a^b;
a=a^b;

7.C和C++的关系
1.在C++中调用被C编译器编译后的函数,为什么要加extern”C”?
C++语言支持函数重载,C语言不支持函数重载,所以函数被C++编译后在库中名字与C语言的不同。假设某个函数的原型为void foo(int x,int y).该函数被C编译器编译后在库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字
C++提供的externC解决名字匹配问题

2.ifndef/define/endif是用来防止头文件被重复引用的

3.C是一种结构化语言,重点在于算法和数据结构,而C++重点在于数据,是面向对象的语言。

4.代码:编写一个函数,实现把C/C++程序代码中的注释去掉,并把结果返回

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <io.h>

void remove_comment(char* buf, size_t size)
{
    char *p, *end, c;
    char *sq_start, *dq_start;
    char *lc_start, *bc_start;
    size_t len;
    p = buf;
    end = p + size;
    sq_start = NULL;//标记单引号
    dq_start = NULL;//标记双引号
    lc_start = NULL;//标记//
    bc_start = NULL;//标记/*

    while (p < end)
    {
        c = *p;
        switch (c)
        {
            case '\'':/*单引号*/
                if (dq_start || lc_start || bc_start)
                {
                    //忽略字符串与注释中的单引号
                    p++;
                    continue;
                }
                if (sq_start == NULL)
                {
                    sq_start = p++;//
                }
                else
                {
                    len = p++ - sq_start;
                    if (len == 2 && *(sq_start + 1) == '\\')
                    {
                        //忽略字符中的单引号
                        continue;
                    }
                    sq_start = NULL;
                }
                break;
            case '\"'://双引号
                if (sq_start || lc_start || bc_start)
                {
                    //忽略字符或注释中的双引号
                    p++;
                    continue;
                }
                if (dq_start == NULL)
                {
                    dq_start = p++;
                }
                else
                {
                    if (*(p++ - 1) == '\\')
                    {
                        //忽略字符串中的双引号
                        continue;
                    }
                    dq_start = NULL;
                }
                break;
            case '/'://斜杠
                if (sq_start || dq_start || lc_start || bc_start)
                {
                    //忽略字符,字符串或注释中的斜杠
                    p++;
                    continue;
                }
                c = *(p + 1);
                if (c == '/')
                {
                    lc_start = p;
                    p += 2;
                }
                else if (c == '*')
                {
                    bc_start = p;
                    p += 2;
                }
                else
                {
                    //忽略除号
                    p++;
                }
                break;
            case '*'://星号
                if (sq_start || dq_start || lc_start || bc_start == NULL)
                {
                    //忽略字符,字符串或行注释中的星号,还有忽略乘号
                    p++;
                    continue;
                }
                if (*(p + 1) != '/')
                {
                    //忽略注释中的星号
                    p++;
                    continue;
                }
                p += 2;
                memset(bc_start, ' ', p - bc_start);
                bc_start = NULL;
                break;
            case '\n':
                if (lc_start == NULL)
                {
                    p++;
                    continue;
                }
                c = *(p - 1);
                memset(lc_start, ' ', (c == '\r' ? (p++ - 1) : p++) - lc_start);
                lc_start = NULL;
                break;
            default:
                p++;
                break;
        }
    }
    if (lc_start)
    {
        memset(lc_start, ' ', p - lc_start);
    }
}


int main()
{
    int fd, n;
    char buf[102400];
    fd = open("D:\\uuu.txt", O_RDONLY, 0);
    if (fd == -1)
    {
        return -1;
    }
    n = read(fd, buf, sizeof(buf));
    if (n == -1 || n == 0)
    {
        close(fd);
        return -1;
    }
    remove_comment(buf, n);
    *(buf + n) = '\0';
    printf(buf);
    return 0;
}

5.
sizeof计算的是栈中分配的大小,如果sizeof对象而对象有静态变量那么是不成立的
注意的是当数组作为函数的参数的时候那么他就退化成了指针
注意sizeof和strlen的区别
(1)得出结果的时期不同,一个是在编译期一个是在运行期
(2)接受的参数类型范围不同,strlen只接受char*并且以’\0’结尾

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值