平时编程过程中一些总结和难点(持续更新中)

1>

int main()
{
    int i = 1;

    switch(i)
    {
    case 1:
        if(1)
    case 2:
    case 3:
        break;
    default:
        break;
    }

    return 0;
}

2> sscanf(buf, "%d%d", &i, &j)

3>

#include <stdint.h>
#include <stdio.h>

int main()
{
    int temp=32,tempTwo=54; //两个整型变量
    int *pTemp=&temp;
    int *pPtemp=&tempTwo; //两个整型指针
    printf("&temp=%x,&tempTwo=%x\n\n\n",&temp,&tempTwo);


    printf("pTemp=%x,pPtemp=%x\n",pTemp,pPtemp);
    printf("地址是:&pTemp=%x,&pPtem=%x\n",&pTemp,&pPtemp);
    printf("*pTemp=%d,*pPtemp=%d",*pTemp,*pPtemp);
    printf("\n\n");
    //下面这条语句看了将近3个小时也没有看出名堂?
    (*(const int **)pPtemp)=pTemp;//看不明白这条语句???!!!
    printf("pTemp=%x,pPtem=%x\n",pTemp,pPtemp);//pPtemp没有变化
    printf("地址是:&pTemp=%x,&pPtem=%x\n",&pTemp,&pPtemp);
    printf("*pTemp=%d,*pPtemp=%d",*pTemp,*pPtemp);//*pPtemp却发生了变化,为什么?


    printf("\n\n**pPtemp=%d",*((int *)*pPtemp));//竟然又是32,而不是54,为什么?
    getchar();
    return 0;
}

4> c++的多态分为运行时多态和编译时多态,编译时多态是通过普通函数重载实现包括运算符重载以及模板体现的;而运行时多态则是通过虚函数体现的。

5> linux下的errno和strerror用法。

6> msgrcv error: Argument list too long --> msglen的长度小于消息体中消息的长度。

7> C语言的题,逻辑或前面不假的话,后面的就不会执行么?是的。

8> 逻辑判断中!-1 为 0即为假

9>在Linux下编译程序有时会遇到这种问题,这貌似是一个Linux历史遗留问题:

/usr/include/sys/types.h:62: error: conflicting types for ‘dev_t’
/usr/include/linux/types.h:13: error: previous declaration of ‘dev_t’ was here
/usr/include/sys/types.h:67: error: conflicting types for ‘gid_t’

开始以为是GCC的版本问题,升级了版本也不好使,后来发现!进入编译出错的文件xxx.cpp:

把所有#include 都提到最前面,把#include 的包含放在其后,就可以编译通过了,之所以出现面的问题是存在循环引用所致。如:

#include <linux/apm_bios.h>
#include <sys/types.h>
变成
#include <sys/types.h>
#include <linux/apm_bios.h>

10> linux 下更新库的时候要注意目录,一般都是从环境变量设置的路径去查找库,例如:QT的环境变量设置export1 LD_LIBRARY_PATH=/usr/lib:/usr/local/tslib/lib:$PWD/firmware:$LD_LIBRARY_PATH

11> 在Linux下编译代码提示:

make: warning: Clock skew detected. Your build may be incomplete 或者 其他时间相关的错误或者警告提示。

这个错误是由于系统时间比文件修改时间早造成的,一般可以通过修改系统时间来消除错误:

date命令查看当前系统时间

date -s 5/18/2011 命令可以修改系统日期
date -s 16:10:59命令可以修改系统时间

总之保证系统时间与文件修改时间迟或新,那么上面的编译警告就不存在了。

解决方法:把虚拟机的系统时间和宿主机的系统时间尽量同步即可。

12> 启动vmware时出现以下错误:

Cannot open the disk 'D:/vmware/Ubuntu.vmdk' or one of the snapshot disks it depends on.

原因: 出现这种情况一般是由于上次在关机的出现了异常,比方说非正常关机,强关机等情况,从而导致产生了一些lck为后辍名的文件,那么解决方法就是删除这些lck文件即可。

解决方法 , d:/vmware目录,删除所有的lck文件即可。

13>

QCoreApplication::sendPostedEvents: Cannot send posted events for objects in another thread

在非GUI线程中操作继承自QObject的对象时会报出此错误,需改为在非GUI线程中发出信号,GUI线程中使用槽函数接收处理才能避免此错误。

14> localhost与127.0.0.1的区别

localhost也叫local ,正确的解释是:本地服务器

127.0.0.1在windows等系统的正确解释是:本机地址(本机服务器)

localhot(local)是不经网卡传输!这点很重要,它不受网络防火墙和网卡相关的的限制。

127.0.0.1是通过网卡传输,依赖网卡,并受到网络防火墙和网卡相关的限制。

一般设置程序时本地服务用localhost是最好的,localhost不会解析成ip,也不会占用网卡、网络资源。

有时候用localhost可以,但用127.0.0.1就不可以的情况就是在于此。猜想localhost访问时,系统带的本机当前用户的权限去访问,而用ip的时候,等于本机是通过网络再去访问本机,可能涉及到网络用户的权限。

15> asmlinkage

asmlinkage是个宏,使用它是为了保持参数在stack中。

看一下/usr/include/asm/linkage.h里面的定义:

#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))

其中 attribute__是关键字,是gcc的C语言扩展。

__attribute__机制是GNU C的一大特色,它可以设置函数属性、变量属性和类型属性等。可以通过它们向编译器提供更多数据,帮助编译器执行优化等。

__attribute
((regparm(0))):告诉gcc编译器该函数不需要通过任何寄存器来传递参数,参数只是通过堆栈来传递。

attribute((regparm(3))):告诉gcc编译器这个函数可以通过寄存器传递多达3个的参数,这3个寄存器依次为EAX、EDX 和 ECX。更多的参数才通过堆栈传递。这样可以减少一些入栈出栈操作,因此调用比较快。

asmlinkage大都用在系统调用中。有一些情况下是需要明确的告诉编译器,我们是使用stack来传递参数的,比如X86中的系统调用,是先将参数压入stack以后调用sys_函数的,所以所有的sys_函数都有asmlinkage来告诉编译器不要使用寄存器来编译,

16>Linux C函数之错误处理函数。

ferror: 检查文件流是否有错误发生

头文件: stdio.h

函数定义: int ferror(FILE *stream);

说明: ferror()用来检查参数stream所指定的文件流是否发生了错误情况, 若有则返回非0值.

perror: 打印出错误原因信息字符串

头文件: stdio.h

函数定义: void perror(const char *s);

说明: perror()用来将上一个函数发生错误的原因输出到标准错误(stderr). 参数s所指的字符串会先打印出, 后面加上错误的原因字符串. 此错误原因依照全局变量errno的来决定要输出的字符串.

应用举例:

#include <stdio.h>

int main(void)
{
    FILE *fp;

    fp = fopen("/tmp/fdsafda", "r+");
    if(fp == NULL)
    {
        perror("fopen");
    }

    return 0;
}

运行结果:

fopen: No such file or directory

strerror: 返回错误原因的描述字符串

头文件: string.h

函数定义: char *strerror(int errnum);

说明: strerror()用来依参数errnum的错误代码来查询错误原因的描述字符串, 然后将该字符串指针返回. 通常给其传递全局变量errno.

应用举例:

#include <stdio.h>
#include <errno.h>

int main(void)
{
    char *buffer;
    buffer = strerror(errno);
    printf("Error: %s\n", buffer);
    return 0;
}

运行结果:

Error: Success

17> 挂载NFS文件系统

DHCP/BOOTP: Ignoring delayed packet

............后面就一直这样,启动不起来

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

解决方法:

1 kernel 配置

-- Network File Systems 
<*> NFS client support 
[*]     NFS client support for NFS version 3 
[ ]         NFS client support for the NFSv3 ACL protocol extension 
[ ]     NFS client support for NFS version 4 (EXPERIMENTAL) 
[*]  Root file system on NFS 
< >  NFS server support

选上Root file system on NFS

2 在uboot下设置参数

内核启动参数参见Documentation/kernel-parameters.txt

它说 ip 这个选项

See Documentation/filesystems/nfs/nfsroot.txt.

ip=<client-ip>:<server-ip>:<gw-ip>:<netmask>:<hostname>:<device>:<autoconf>

我的配置:

setenv bootargs 'console=ttyO2,115200n8 rootwait rw mem=256M notifyk.vpssm3_sva=0xBEE00000 vram=20M root=/dev/nfs nfsroot=192.168.0.188:/home/m/rfs_816x/ ip=192.168.0.118:192.168.0.188:192.168.0.1:255.255.255.0:skypine:eth0:on  noinitrd'
saveenv

3 nfs作为根是起来了。可能是启动顺序的不一致吧,原来作为jffs2启动的镜像改成nfs就会报

Warning: unable to open an initial console.

这个主要是没有建立控制台,解决方式:

缺少 /dev/console 和 /dev/null

在建立他們之前UDEV就先使用到他們了

cd /dev
mknod -m 660 console c 5 1
mknod -m 660 null c 1 3

18>C++构造函数后加冒号

其实冒号后的内容是初始化成员列表,一般有三种情况:

1、对含有对象成员的对象进行初始化。

2、对于不含对象成员的对象,初始化时也可以套用上面的格式。

3、对父类进行初始化。



在C++中,构造函数有个特殊的初始化方式叫“初始化表达式表”(简称初始化表)。初始化表位于函数参数表之后,却在函数体 {} 之前。这说明该表里的初始化工作发生在函数体内的任何代码被执行之前。

构造函数初始化表的使用规则:

1.如果类存在继承关系,派生类必须在其初始化表里调用基类的构造函数。

2.类的const 常量只能在初始化表里被初始化,因为它不能在函数体内用赋值的方式

3. 类的数据成员的初始化可以采用初始化表或函数体内赋值两种方式,这两种方式的效率不完全相同。方式一:在初始化列表中初始化;方式二:在构造函数内部初始化。

19> QString与char *之间的转换

QString转char

先将QString转换为QByteArray,再将QByteArray转换为char


注意:不能用下面的转换形式char *mm = str.toLatin1().data();。因为这样的话,str.toLatin1()得到的QByteArray类型结果就不能保存,最后转换,mm的值就为空。

char * 转QString

可以使用QString的构造函数进行转换:QString(const QLatin1String &str);

QLatin1String的构造函数:QLatin1String(const char *str);

则如下语句是将char * mm转换为QString str:

str = QString(QLatin1String(mm));

20> onvif probe不成功,经发现是因为路由器不支持广播,换其他支持广播的路由器就可以,交换机支持广播。

21> malloc只是分配了地址,内存没有用到,只有用到这个地址的时候。free查看内存的时候才能够体现,时间占用的内存。

22> qt为什么只能在主线程里进行UI操作?对Qt而言,一个进程里和窗口系统(譬如Win32的GDI, linux下的X11)UI事件关联的只有主UI线程,而并没有设计成多线程和系统窗口系统同时交互(复杂性,安全性,性能等原因),这应该是根源。一个原则:涉及到界面修改的部分,必须在UI线程中进行。






原文链接: https://www.cnblogs.com/cslunatic/archive/2013/06/07/3125300.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/91583

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月10日 上午1:14
下一篇 2023年2月10日 上午1:15

相关推荐