c语言编写经验逐步积累3

寥寥数笔,记录我的C语言盲点笔记,只为曾经经历过,亦有误,可交流。

1.typedef来定义一个函数指针类型的方法,定义一个新的函数指针类型。

:建立一个类型别名的方法很简单,在传统的变量声明表达式里用类型名替代变量名,然后把关键字typedef加在该语句的开头”。

typedef int (*PFUN)(): 定义PFUN这个函数指针类型,由编译器自动来完成,比如PFUN pfun;定义了一个函数指针,类似于抽象出一种新的变量类型。

typedef unsigned short (*pTaskEventHandlerFn)( unsigned char task_id, unsigned short event );

pTaskEventHandlerFn tasksArr[];//申明函数指针的数组

使用typedef将一个类型名字替代原先申明时的变量名,然后类型名可以用来申明定义变量。

2.有初始化的数组定义可以省略方括号中的数组大小。

  例如,下面的代码中数组定义为5个元素:
    int a[]={2,4,6,8,10};
  编译时必须知道数组的大小。通常,声明数组时方括号内的数字决定了数组的大小。有初始化的数组定义又省略方括号中的数组大小时,编译器统计花括号之间的元素个数,以求出数组的大小。
  例如,下面的代码产生相同的结果:
    static int a1[5]={1,2,3,4,5};
    static int a2[]={1,2,3,4,5};

2,栈顶一般为低地址,函数入栈一般参数从右往左进行。

3.for(a;b;c){e}执行顺序:

先进行a, 然后是b, 执行e, 在执行c.进一步执行b,执行e,c.直到b不再满足退出循环。

4.union数据类型,内存是重叠的,完全一样

typedef union {
  uint32 time32;
  uint16 time16[2];
  uint8 time8[4];
} osalTime_t;

对time32的赋值后,访问其他类型时依旧是原来的内存。三个成员占据一样的数据空间,起始地址都是一样的,一旦一个成员数值变化就会出现其他成员取值也发生变化

5.inline内联函数总结

内联函数具有代码量小且直接编译进可执行文件中,不进行call调用,也就是在不同的文件的函数如果调用内联函数,则不同的函数都会出现该内联函数的可执行代码。

但是,如果不重复调用的话,内联函数带来的好处就是执行更加快速,无需再call,以及函数参数的出入栈SP,保护栈帧,跳出函数,清空栈帧等各种耗时。起到快速执行的效果。故内联函数的代码量都较小。

总之是以增加执行文件大小来获取程序执行速度的提高。

6.(int *)0,表示指向一个整形的地址,地址值为0,即空指针所在的地方,该处一般不允许写操作,以免破坏系统,但可以读取。

7.如果一个函数要被其他文件中函数使用,定义时加extern关键字,在没有加extern和static关键字时,一般编译器会默认是extern类型的,因此你在其他函数里调用也可以使用。

8.结构体之offsetof宏详细解析 ,#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE*)0)->MEMBER) (include/linux/stddef.h)

9.32位机读取一个字节,实际底层的汇编做了进一步的处理。

比如读取一个字节,实际返回的是一个32位,经过屏蔽移位取得你要的地址所在的数。写入时也一样,会先保持4字节其他字节不变,然后单独把要写入的字节做改变。由编译器根据你的数据类型来完成实际的实现。

32字节的读取最为高效。

10.中断发生时,未完成服务程序的处理时,将会忽略挂起Pending,优先级高的中断可以获取中断使用权。

另一个同样的中断发生,直到当前中断处理完成,才允许再次中断进入。

11.switch case误区。

switch case往往对不同的命令进行分类操作,但是如果出现遇到对应case做完处理后,如果没有遇到break就会接着默认执行下面的case内容(不再去case,因为只有刚进入switch才会去匹配case,已经进入后,case匹配忽略)。直到遇到带break后为止跳出case,否则一直执行完。

因为只在第一次才做switch判断跳到对应的内容去执行。所以,好的程序基本是需要break的,但是有些情况(多个情况对应处理的内容要一样,即前面的几个类型可以不做处理,不需要break,直到最后一个做处理,实现多个类型执行相同的功能,但不增加代码量,更直接)。

总之,只有在第一次才做判断与选择,进入以后就是安装顺序执行,不break会一直执行到switch结束

12 C语言中的感叹号!逻辑取反,不同于~的按位取反

!=:表示不等于。!(1)表示为0,!(0)表示为1,有取反之意,但只能用在0和1上面。不等于0的会变为0,等于0的变为1

13.C语言+和<<遇到的一个BUG问题。

在这里+的优先级高于<<左右移。所以比如a<<8+b,实际是从右往左赋值,8+b相加后来移动a,所以不实现两个字节合并为一个16位的数据。故要加(a<<8)+b才能实现本来的意图,这个误区需要注意。

14.:#define PINMUX0_31_28 0x00000001u,0x00000001UL

u表示无符号,UL unsigned long int 32位,unsigned long long 64位

15数组指针和指针数组的区别

数组指针,为一个指针,int (*a)[10];指向一个数组,类似于函数指针

指针数组,为一个数组,int* a[10];类似于指针函数,返回的是一个指针。

16.window下面绝对路径的文件需要用双斜杠来表示\\

17 printf("c=%#x\n",c);什么意思?

%#表示的输出提示方式,如果是8进制,在前面加0,如果是十进制,不加任何字符,如果是十六进制,会自动加上0x

18 静态变量在编译的时候初始化,所以初值必须是常量(可以是常数、定义成常数的宏、C++编译器中用const修饰的常量),静态变量不能用变量赋初始值,但在运行时是可以用变量赋值的。

19 assert函数,用于判断是否为真,满足就继续执行,不然直接终止程序的运行

20.做到4个字节对齐,使用如下方式:

((CSL_CacheRegsOvly)CSL_CACHE_REGS)->L1DIWC  = ((byteCnt+3)>>2);

字节数不为4的倍数时,需要多保留一个字的数量,故加3,1+3,2+3,3+3.4字节对齐的方式,

获得4字节对齐后的字节数字:

byte_num = (byte + 3) & 0xfc; 这样字节数必为4的倍数。

21 for循环中如果break,则i++不再执行。

22.temp = (temp+1)&7.表示temp从0到7变化,循环。类似于temp=8时赋值回0.

23.unsigned char *p;

unsigned char a[];

p=a;这样正确。

unsigned int p1= a;错误,因为是指针类型赋值给了整形的数据类型,类型不匹配。

unsigned char * p[10]:申明一个指针数组,10个指针,每个指针指向char类型的空间。

unsigned char (*p)[10]申明一个数组指针,指向含有10个char类型的空间,指针维护一个10的空间,偏移1加10个空间。

24.

多个if会进行分支处理,分别判断后进行是否执行。

而if 和多个else if等配合时,一旦出现某个满足条件时,不再执行下面的else if的判断,确保只进入一个分支。

25. char a[3][4]. char **p =a;出现编译错误,类型不匹配不能赋值

因为a表示的是一个指向一维数组的指针,即char (*a)[3]这个类型.a+1是会偏移3个单位。

p是一个指针的指针,称为二级指针。所以两者类型不一样。

26.数组名取地址

在《C和指针》p142中说到,在以下两中场合下,数组名并不是用指针常量来表示,就是当数组名作为sizeof操作符和单目操作符&的操作数时。 sizeof返回整个数组的长度,而不是指向数组的指针的长度。 取一个数组名的地址所产生的是一个指向数组的指针,而不是一个指向某个指针常量的指针。
所以&a后返回的指针便是指向数组的指针(类似于(*p)[3]),跟a(一个指向a[0]元素的指针)在指针的类型上是有区别的。&a+1是偏移一个数组sizeof大小的尺寸,因为&a是指向数组指针的地址,是一个数值指针。

但是作为形参时,一级数组名就转为了一个普通的一级指针而已。

27. 二维数组名不能简单的理解为2级指针,而是要从数组的系统结构上去了解。

个人认为二维数组名其实就是一个指针,但是他指向的数据类型是一维数组的这么个数据类型。即数值指针,其实可以理解为功能和二维数组名类似。至于数据访问,完全是编译器来自动完成栈区的访问。

28.数值名不能修改,是因为在栈区域内已经定好了ebp,基地址。访 问数组都是基于这个ebp来进行的。所以,给数组名赋值变得没有意义,肯定不允许修改ebp的。所以在编译阶段就报错。

29.

fseek和发tell配合来完成确定文件大小的过程。

fseek(fPtr,0,SEEK_END);

file_size = ftell(fPtr);

fseek(fPtr,0,SEEK_SET),位置指针复位进行读写操作

30.两数交换不使用第三个缓冲区,三条代码的方法:主要通过运算符来实现。

A = A^B;

B = A^B;

A = B^A;

A = A+B;

B = A-B;

A = A-B;

c语言编写经验逐步积累3

时间: 2024-10-12 19:56:09

c语言编写经验逐步积累3的相关文章

c语言编写经验逐步积累4

寥寥数笔,记录我的C语言盲点笔记,只为曾经经历过,亦有误,可交流. 1.逻辑表达式的使用 取值 = 表达式 ? 表达式1:表达式2: 比如x = y > z ? y:z 2."+,-"等逻辑运算符优先级大于移位,移位大于逻辑运算 3. sizeof在编译时由编译器完成,对其传入的参数不做运算处理. sizeof(i++);返回4:不会对实际的i进行操作 sizeof和strlen的区别是,后者是运算时执行. 返回遇到非NULL时的字符个数. sizeof处理数组名时会统计分配的内

shell简介 linux由什么语言编写

1.shell简介 Shell本身是一个用C语言编写的程序,它是用户使用Linux的桥梁.Shell既是一种命令语言,又是一种程序设计语言.作为命令语言,它交互式地解释和执行用户输入的命令:作为程序设计语言,它定义了各种变量和参数,并提供了许多在高级语言中才具有的控制结构,包括循环和分支.它虽然不是Linux系统核心的一部分,但它调用了系统核心的大部分功能来执行程序.建立文件并以并行的方式协调各个程序的运行.因此,对于用户来说,shell是最重要的实用程序,深入了解和熟练掌握shell的特性极其

《C语言编写 学生成绩管理系统》

/* (程序头部凝视開始)* 程序的版权和版本号声明部分* Copyright (c) 2011, 烟台大学计算机学院学生 * All rights reserved.* 文件名: 学生成绩管理系统 * 作 者: 刘江波 * 完毕日期: 2012 年 6 月 23 日* 版 本 号: v.623 * 对任务及求解方法的描写叙述部分 * 程序头部的凝视结束 */ #include "stdio.h" #include"string" /*定义学生结构体*/ struc

【原创】用第三方语言编写PostgreSQL 存储函数

在PostgreSQL里,所有的存储函数需求都可以用PLPGSQL来实现.同时也支持用第三方语言来编写,这个就得看自己哪个方面熟练了.不过要注意的一点是 PLPGSQL的效率怎么着都比其他第三方语言来的高效.比如,简单的插入表的存储函数: CREATE OR REPLACE FUNCTION ytt.insert_plpgsql(f_num integer) RETURNS void LANGUAGE plpgsql AS $ytt$ declare i int := 0; v_rank int

基于Perfect用Swift语言编写Slack聊天机器人

基于Perfect用Swift语言编写Slack聊天机器人 本项目是专门为Slack聊天机器人定制的模板服务器. 完整的源代码下载在Github https://github.com/PerfectServers/SlackBot 在本项目模板中,一个聊天机器人可以加入授权频道,读取频道内所有用户发送的"曲奇"并记录在案,而且可以直接答复用户的有关曲奇饼干的问题. 预备知识 在您决定编译.测试或者部署您自己的基于Perfect软件框架体系的聊天机器人之前,以下基础知识??不可或缺??:

ubuntu 下使用CGI c语言 编写helloworld

从根本上说,CGI 就是HTML表单与服务端脚本之间的接口. 自己可以百度了一些cgi知识:给出链接报错.那就自己Google哈 也因为工作需要,所以来学习了下. 一.安装及配置apache服务器 安装apache2服务器 #sudo apt-get install apache2 配置apache2服务器 配置文件位于 /etc/apache2/sites-enabled/000-default 用vi打开配置文件: #sudo vi /etc/apache2/sites-enabled/00

Oracle存储过程的编写经验与优化措施

1.开发人员如果用到其他库的Table或View,务必在当前库中建立View来实现跨库操作,最好不要直接使用"databsevv.dbo.table_name",因为sp_depends不能显示出该SP所使用的跨库table或view,不方便校验. 2.开发人员在提交SP前,必须已经使用set showplan on分析过查询计划,做过自身的查询优化检查. 3.高程序运行效率,优化应用程序,在SP编写过程中应该注意以下几点: a) SQL的使用规范: i. 尽量避免大事务操作,慎用ho

运用Python语言编写获取Linux基本系统信息(三):Python与数据库编程,把获取的信息存入数据库

运用Python语言编写获取Linux基本系统信息(三):Python与数据库编程 有关前两篇的链接: 运用Python语言编写获取Linux基本系统信息(一):获得Linux版本.内核.当前时间 运用Python语言编写获取Linux基本系统信息(二):文件系统使用情况获取 一.实验环境: Python2.7.10.pycharm.VM虚拟机.CentOS6.3.mysql 二.MySQLdb模块: MySQLdb模式是Python中专门连接MySQL数据库的模块,另外Python开发环境的搭

通过WebSocket实现实时通讯C#语言编写服务端

无意中发现js有webSocket对象于是百度了一下客户端代码与服务端代码没有现成的 有的就有一些简单了连接例子有的还不好使 于是就自己整理了一下 c#编写的服务端代码 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.Net.Sockets; using System.Text.RegularExpression