当前位置 博文首页 > 小萌新~小白的博客:c语言编程的小细节

    小萌新~小白的博客:c语言编程的小细节

    作者:[db:作者] 时间:2021-08-09 10:06

    Volatile的使用
    
    echo命令的使用。
    
    wchar_t数据类型一般为16位或32位,但不同的C或C++库有不同的规定,如GNU?Libc规定wchar_t为32位,总之,wchar_t所能表示的字符数远超char型
    1.定义方法wchar_t *chinese_str = L"韦东山g";
    2.For语句的一些灵活用法。
    for ( i = x, p = 0; i < x_max; i++, p++ )
    3.continue用法c语言
    Continue的用法是,结束本次循环,但是不跳出循环。
    Break的用用法是,结束循环,跳出循环体。
    4.lcd显示的代码,带颜色
    for ( i = x, p = 0; i < x_max; i++, p++ )
      {
        for ( j = y, q = 0; j < y_max; j++, q++ )
        {
          if ( i < 0 || j < 0 || i >= var.xres || j >= var.yres )
            continue;
    
          //image[j][i] |= bitmap->buffer[q * bitmap->width + p];
          lcd_put_pixel(i, j, bitmap->buffer[q * bitmap->width + p]);
        }
      }
    5.lcd打印字符的ascii
    void lcd_put_ascii(int x, int y, unsigned char c)
    {
    	unsigned char *dots = (unsigned char *)&fontdata_8x16[c*16];
    	int i, b;
    	unsigned char byte;
    
    	for (i = 0; i < 16; i++)
    	{
    		byte = dots[i];
    		for (b = 7; b >= 0; b--)
    		{
    			if (byte & (1<<b))
    			{
    				/* show */
    				lcd_put_pixel(x+7-b, y+i, 0xffffff); /* 白 */
    			}
    			else
    			{
    				/* hide */
    				lcd_put_pixel(x+7-b, y+i, 0); /* 黑 */
    			}
    		}
    	}
    }
    6.mmap的使用
    https://blog.csdn.net/yangle4695/article/details/52139585
    mmap将一个文件或者其它对象映射进内存。文件被映射到多个页上,如果文件的大小不是所有页的大小之和,最后一个页不被使用的空间将会清零。mmap在用户空间映射调用系统中作用很大。
    头文件 <sys/mman.h>
    函数原型
    void* mmap(void* start,size_t length,int prot,int flags,int fd,off_t offset);
    参数start:指向欲映射的内存起始地址,通常设为 NULL,代表让系统自动选定地址,映射成功后返回该地址。
    
    参数length:代表将文件中多大的部分映射到内存。
    
    参数prot:映射区域的保护方式。可以为以下几种方式的组合:
    PROT_EXEC 映射区域可被执行
    PROT_READ 映射区域可被读取
    PROT_WRITE 映射区域可被写入
    PROT_NONE 映射区域不能存取
    
    参数flags:影响映射区域的各种特性。在调用mmap()时必须要指定MAP_SHARED 或MAP_PRIVATE。
    MAP_FIXED 如果参数start所指的地址无法成功建立映射时,则放弃映射,不对地址做修正。通常不鼓励用此旗标。
    MAP_SHARED对映射区域的写入数据会复制回文件内,而且允许其他映射该文件的进程共享。
    MAP_PRIVATE 对映射区域的写入操作会产生一个映射文件的复制,即私人的“写入时复制”(copy on write)对此区域作的任何修改都不会写回原来的文件内容。
    MAP_ANONYMOUS建立匿名映射。此时会忽略参数fd,不涉及文件,而且映射区域无法和其他进程共享。
    MAP_DENYWRITE只允许对映射区域的写入操作,其他对文件直接写入的操作将会被拒绝。
    MAP_LOCKED 将映射区域锁定住,这表示该区域不会被置换(swap)。
    
    参数fd:要映射到内存中的文件描述符。如果使用匿名内存映射时,即flags中设置了MAP_ANONYMOUS,fd设为-1。有些系统不支持匿名内存映射,则可以使用fopen打开/dev/zero文件,然后对该文件进行映射,可以同样达到匿名内存映射的效果。
    
    参数offset:文件映射的偏移量,通常设置为0,代表从文件最前方开始对应,offset必须是分页大小的整数倍。
    
    返回值:
    
    若映射成功则返回映射区的内存起始地址,否则返回MAP_FAILED(-1),错误原因存于errno 中。
    数码相框项目的笔记:
    理解一个项目,先去慢慢的去看他的源程序,慢慢来,花几天弄明白了,再去看视频。
    7.对freebuffer的操作。
    https://blog.csdn.net/pk_20140716/article/details/46808163
    8.memset的使用。
    1. memset()函数原型是extern void *memset(void *buffer, int c, int count) ?????? buffer:为指针或是数组,
    ????????????? c:是赋给buffer的值,
    ?????? count:是buffer的长度.
    ?????? 这个函数在socket中多用于清空数组.如:原型是memset(buffer, 0, sizeof(buffer))
    ?????? Memset?用来对一段内存空间全部设置为某个字符,一般用在对定义的字符串进行初始化为‘ ’或‘/0’;
    ????? 例:char a[100];memset(a, '/0', sizeof(a));
    ????memset可以方便的清空一个结构类型的变量或数组。
    9.strcmp函数的使用。
    strcmp函数是string compare(字符串比较)的缩写,用于比较两个字符串并根据比较结果返回整数。基本形式为strcmp(str1,str2),若str1=str2,则返回零;若str1<str2,则返回负数;若str1>str2,则返回正数。
    10.strncmp函数的使用。
    strncmp函数为字符串比较函数,字符串大小的比较是以ASCII 码表上的顺序来决定,此顺序亦为字符的值。其函数声明为int strncmp ( const char * str1, const char * str2, size_t n );功能是把 str1 和 str2 进行比较,最多比较前?n?个字节,若str1与str2的前n个字符相同,则返回0;若s1大于s2,则返回大于0的值;若s1 小于s2,则返回小于0的值。
    11.getopt() 所设置的全局变量包括:
    	char *optarg——当前选项参数字串(如果有的话)。不是选项的字串,如上命令的话,它的值先是"qing er",后是123。
    int optind——argv的当前索引值(下一个argv)。当getopt()在while循环中使用时,循环结束后,剩下的字串视为操作数,在 argv[optind]至argv[argc-1]中可以找到剩下的那些操作数。
    int opterr——opterr非零表示产生的错误要输出到stderr上,初值为1。
    int optopt——当发现无效选项字符之时,getopt()函数或返回'?'字符,或返回':'字符,并且optopt包含了所发现的无效选项字符。它还是一个选项,是不在选项字串"a:b:cd::e"中的选项,但不是程序参数(操作数),不是选项参数。
    12.strtoul的使用:
     dwFontSize = strtoul(optarg, NULL, 0);将optarg转换为十进制。
    13.13.strncpy?的使用
    是?C语言的库函数之一,来自 C语言标准库,定义于?string.h,char *strncpy(char *dest, const char *src, int n),把src所指向的字符串中以src地址开始的前n个字节复制到dest所指的数组中,并返回dest。
    格式
    函数原型char*strncpy(char*dest,char*src,size_tn);
    14.Makefile的语法。
    Filter将不符合规则的目标文件过滤出去,留下想要的目标。
    Patchat找到内容替换成另外一种格式的文件
    
    以下是注解:
    # obj-y := a.o b.o c/ d/
    # $(filter %/, $(obj-y))   : c/ d/
    # __subdir-y  : c d
    # subdir-y    : c d
    __subdir-y	:= $(patsubst %/,%,$(filter %/, $(obj-y)))
    Filter—out把不匹配的选项留下来,其他全部过滤。
    15.函数的名字相同,但是形参列表不同,则为函数重载函数。
    16.函数指针 
    fun(1,2);
        void (*pf)(int,int);
        pf = fun;
        pf(1,2);
    17.阻塞调用:当没有获得资源是,进程挂起。节省CPU资源。
    18.链表和队列。
    19.原子操作,不能被打断,已经分的不能再分了。
    20.互斥锁:
    使用互斥锁(互斥)可以使线程按顺序执行。通常,互斥锁通过确保一次只有一个线程执行代码的临界段来同步多个线程。互斥锁还可以保护单线程代码。
    21.pthread:
    除非线程是被分离的,否则在线程退出时,它的资源是不会被释放的。
    22.注册驱动之后,创建类,然后在类下面创造设备。
    23.Ioremap()函数,映射从物理地址映射到虚拟地址。出口函数用iounmap函数释放掉映射的地址。
    24.指针+1,的操作是以指针所指向的长度决定的,int类型的指针加4字节,long类型的指针加16字节。
    25.从用户空间到内核空间的数据传递函数 copy_from_user()
    26.从内核空间到用户空间的数据传递函数 copy_to_user()
    27.一个主设备号可以有多个此设备号。获取此设备号
    28.poll_wait函数只是为了能让驱动程序找到唤醒的程序
    29.按键的去抖动,是按键按下触发按键中断,接着触发定时器中断。
    30.MAJOR(inode->i_rdev)(提取主设备号)
    31.Miner(inode->i_rdev)(提取次设备号)Input.c {input_drv,input_handler};让(就是让“input_device”与“id_table”作比较)如果支持硬件设备,那就进行链接。
    32.环形缓冲区实质是一个数组。
    33.定义定时器的用timer_list
    34.上报事件:这个还不理解怎么上报的。
    input_report_abs(s3c_ts_dev, ABS_PRESSURE, 0);
    		input_report_key(s3c_ts_dev, BTN_TOUCH, 0);
    		input_sync(s3c_ts_dev);
    35.以二进制查看文件:hexdump  文件目录
    36.编译内核:
    $ tar xjf linux-2.6.22.6.tar.bz2 
    //解压 linux-2.6.22.6.tar.bz2 
    $ cd linux-2.6.22.6 
    //进入 linux-2.6.22.6 目录 
    $ patch -p1 < ../linux-2.6.22.6_jz2440_v2v3.patch //给 linux-2.6.22.6 打 patch 补丁 
    $ cp config_ok .config //拷贝开发板配置文件 
    $ make uImage //编译内核生成 uImage 镜像 
    编译好的内核,拷贝到跟文件系统中去;
    cp uImage /work/nfs_root/first_fs
    2.然后下载到内核分区:
    3.使用nfs下载:nfs 0x30000000 192.168.0.102:/work/nfs_root/uImage
    4.(删除前2M的flash :nand erase 0 0x200000)
    5.(烧写uImage :nand write.jffs2 0x32000000 0 $(filesize))
    6.从地址0x30000000启动内核:bootm 0x32000000或者nboot 0x32000000 0 0
    7.构建根文件系统:(u_boot的目的启动内核,内核启动应用程序)
    8.tar xjf busybox-1.7.0.tar.bz2
    9.cd busybox-1.7.0/
    10.make menuconfig 配置
    11.Make编译
    12.安装之前创建一个目录mkdir -p /work/nfs_boot/first_fs
    13.Make CONFIG_PREFIX=/work/nfs_boot/first_fs install安装
    14.cd /work/nfs_root/first_fs
    15.Ls /dev/console /dev/null -l
    16.Mkdir dev
    17.Cd dev
    18.Sudo Mknod console c 5 1
    19.Sudo mknod null c 1 3 
    20.Cd ..
    21.Mkdir etc
    22.Vi etc/inittab (console::askfirst:-/bin/sh)
    23.创建lib目录
    24.Mkdir /work/nfs_root/first_fs/lib
    25.cd /work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib
    26.Cp “.so” /work/nfs_root/first_fs/lib -d
    27.制作映像文件,跟文件系统下载到开发板上去
    28.Cd /work/system
    29.tar xjf yaffs_source_util_larger_small_page_nand.tar.bz2 
    30.Cd /work/system/Development/yaffs2/utils$
    31.Make生成跟文件系统的映像文件
    32.
    33.sudo cp mkyaffs2image /usr/local/bin/
    34.sudo chmod +x /usr/local/bin/mkyaffs2image
    35.cd /work/nfs_root/
    36.Mkyaffs2image first_fs first_fs.yaffs2
    37.Cd /work/nfs_root/first_fs
    38.Mkdir proc
    39.然后在linux系统上去挂载跟文件操作
    40.在linux单板上去创建proc文件
    41.Mkdir proc
    42.Mount -t proc none /proc
    43.实现自动挂载在配置文件(::sysinit:/etc/init.d/rcS),然后创建一个脚本文件
    44.Mkdir etc/init.d
    45.Vi etc/init.d/rcs(mount -t proc none /proc)
    46.然后加上一个可执行的属性
    47.Chmod +x etc/init.d/rcS
    48.Mount -a 读出etc文件的内容,依赖于/etc/fstab文件
    49.创建/etc/fstab文件
    50.Vi etc/fstab内容如下:
    51.# cat etc/fstab
    52.# device     mount-point    type   options        dump  fsck order
    53.proc           /proc        proc   defaults        0     0
    54.tmpfs          /tmp         tmpfs  defaults        0     0
    55.制作jffs2的跟文件适合nor flash启动,有一处与书上不同。 
    mkfs.jffs2 -n -s 2048 -e 128KiB -d first_fs -o first_fs.jffs2
    56.用nfs挂载:
    57.Ifconfig
    58.Ifconfig eth0 up
    59.Ifconfig
    60.配置ip
    61.Ifconfig eth0 192.168.0.104
    62.Ping 192.168.0.102拼服务器ip
    63.手动挂接。从flash上启动跟文件系统。在挂接nfs
    64.用单板挂接。Mount -t nfs -o nolock 192.168.0.102:/work/nfs_root/first_fs mnt
    65.不用每次手动挂载,从网络文件系统启动就可挂载,修改启动参数。从网络系统文件启动。
    66.bootargs=noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0,115200
    67.Set bootargs noinitrd root=/dev/nfs nfsroot=192.168.0.102:/work/nfs_root/first_fs ip=192.168.0.109:192.168.0.102:192.168.0.106:255.255.255.0::eth0:off init=/linuxrc console=ttySAC0
    68.save
    69.Client_ip表示单板的ip 192.168.0.109
    70.安装交叉编译器3.4.5的安装地址/work/tools/gcc-3.4.5-glibc-2.3.6/lib/gcc/arm-linux/3.4.5/specs
    71.Source /etc/profile
    交叉只是要把文件加到sudo vi /etc/environment处(PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/ 
    usr/local/arm/4.3.2/bin" 
    )
    72.然后使环境变量生效:source /etc/environment
    37.手动挂载:
    1.先设置网段:ifconfig eth0 192.168.0.106
    2.看看能不能拼通:ping 192.168.0.102
    3.挂载:mount -t nfs -o nolock 192.168.0.102:/work/nfs_root/fs_mini_mdev mnt
    4.写成一句话执行:ifconfig eth0 192.168.0.106;ping 192.168.0.102;mount -t nfs -o nolock 192.168.0.102:/work/nfs_root/fs_mini_mdev mnt
    5.ifconfig eth0 192.168.0.106;mount -t nfs -o nolock 192.168.0.102:/work/nfs_root/fs_mini_mdev mnt
    38. kzalloc这个函数就是原来的两个函数的整合 , 即原来我们每次申请内存的时候都会这么做 , 
    	 先是用 kmalloc() 申请空间 , 然后用 memset()来初始化 , 而现在省事了 , 一步到位 , 直接调用 kzalloc()
    38.kfree();只能用来释放kmalloc()申请的动态空间。不然会导致内核崩溃,出现oops信息。并且kmalloc();申请后的空间需要进行初始化,比如memset();
    39. str 为要转换的字符串,endstr 为第一个不能转换的字符的指针,base 为字符串 str 所采用的进制。
    40.【函数说参数 base 范围从2 至36,或0。参数base 代表 str 采用的进制方式,如base 值为10 则采用10 进制,若base 值为16 则采用16 进制等。
    41.
    42.明】strtol() 会将参数 str 字符串根据参数 base 来转换成长整型数(long)。
    43.c++在程序在对象销毁前会自动调用析构,无须手动调用,而且只会调用一次 
    44.c++静态成员函数只能访问静态成员变量
    45.c++//利用模板提供通用的交换函数 template<typename T>
    46.互换容器 
    cout << "互换后" << endl; 
    47.v1.swap(v2); 
    48.reserve(int len); //容器预留len个元素长度,预留位置不初始化,元素不可访问。vector<int>v;v.reserve(1000);预留1000个元素的位置。
    49.重新指定链表的大小//重新指定大小 L1.resize(10);
    50.insert(pos,elem);//在pos位置插elem元素的拷贝,返回新数据的位置。
    51.链表排序//排序 L.sort(); //默认的排序规则 从小到大 
    52.对vector的赋值的操作v3.assign(v1.begin(), v1.end()); 
    53.Vector只能进行尾部的删除,deque可以两端进行删除,其余的差不多。
    Stack概念:stack是一种先进后出(First In Last Out,FILO)的数据结构,它只有一个出口
    54.set/multiset所有元素都会在插入时自动被排序(set和multiset区别: 
    set不允许容器中有重复的元素 
    multiset允许容器中有重复的元素)
    55.c++中最常见的算法for_each
    56./*检测到内存申请失败,通过调用 abort 来终止程序运行*/
    		assert(pLQNode);
    57.指针操作的释放,是把指针指向的内存给释放了。
    58.队列可以认为是一个双向的链表,只是先入先出。
    59.先序遍历:	
    1.先访问跟节点;
    2.在先序访问左节点;
    3.在先序访问右节点;
    60.中序遍历:	
    1.中序遍历左节点;
    2.在访问跟节点;
    3.在中序访问右节点;
    61.后续遍历:
    1.中序访问左节点;
    2.在中序访问右节点;
    3.在访问跟节点;
    
    62.//释放数组 delete 后加 [] 
    delete[] arr; 
    63.fork函数只能够产生本任务的镜像。要使用exec配合才能够启动新的任务。
    64系统调用是调用内核的sys_函数。
    
    
    cs
    下一篇:没有了