注释


编译器会用空格代替代码中原来的注释,并先于预处理指令执行
/*…*/ 这种形式的注释不能嵌套
只要斜杠(/)和星号(*)之间没有空格,都会被当作注释的开始。例如这样:
y = x/*p;

\ 是一个接续符,表示断行。编译器会将反斜杠剔除掉,跟在反斜杠后面的字符自动接续到前一行。但是注意:反斜杠之后不能有空格,反斜杠的下一行之前也不能有空格。(有的编译器有空格可以通过)。\ 还能被用作转义字符的开始标识。

位运算符


交换两个变量的值:a ^= b; b ^= a; a ^= b;

0x01<<+;
// ==32
// "+"号的优先级比移位运算符的优先级高

在 32 位系统下:

0x01<<+;
0x01<<-;

左移和右移的位数不能大于数据的长度,不能小于0。(有的编译器还是可以通过的)

对于有符号数,在>>右移时,符号位将随同移动。当为正数时,最高位补0;

而为负数时,符号位为 1,最高位是补 0 或是补 1 取决于编译系统的规定。Turbo C 和很多系统规定为补 1。

常用的位操作宏:

#define  SETBIT(x, y)  ((x) |=  (y))
#define CLRBIT(x, y) ((x) &= ~(y))
#define TOGLBIT(x, y) ((x) ^= (y))
#define TESTBIT(x, y) ((x) & (y))
#define SETBIT(x, y)  ((x) |= 1<<(y))
#define CLRBIT(x, y) ((x) &= ~(1<<(y)))

花括号


char a[]{ = “abcde”};

花括号的作用就是打包。

自加减++、--


i=;
(++i)+(++i)+(++i); //未定义行为,取决于编译器
// TCC:15, VC6:16, GCC:18
i=3;
(i++)+(i++)+(i++);

自加或自减运算是在本计算单位计算结束( 遇到 , 或 ; )之后再自加或自减。

int i,j;
i=;
j=(i++,i++,i++); //j=2,i=3 i=;
j=(++i,++i,++i); //j=3

/ 和 %


有2组计算

/; (-)/; /(-); (-)/(-);
%; (-)%; %(-); (-)%(-);

优先级


. []和() 的优先级比 * 高
== 和 != 优先级高于位操作
== 和 != 优先级高于赋值符
算术运算符高于位移运算符

*p++

* 和 ++ 是同优先级,其结合方向为自右向左,因此 *p++ 等价于

*(p++)

预处理


预处理指令是编译器的功能,不是C语言的一部分。

宏定义

ANSI 标准 C 还定义了如下几个宏:
_LINE_ 表示正在编译的文件的行号
_FILE_ 表示正在编译的文件的名字
_DATE_ 表示编译时刻的日期字符串,例如: "25 Dec 2007"
_TIME_ 表示编译时刻的时间字符串,例如: "12:30:55"
_STDC_ 判断该文件是不是定义成标准 C 程序

下面的写法都是对的:

#define EMPTY
# define EMPTY

在使用宏函数的时候,宏名和参数之间的空格会被编译器忽略掉。定义宏的时候空格是有效的。

#error 预处理指令的作用是,编译程序时,只要遇到 #error 就会生成一个编译错误提示消息,并停止编译。其语法格式为:
#error error-message

#line 的作用是改变当前行数和文件名称,它们是在编译程序中预先定义的标识符。命令的基本形式如下:
#line number["filename"]

#pragma 指令的作用是设定编译器的状态或者是指示编译器完成一些特定的动作。

#和##都是预处理命令。

断言assert

#if !defined(NDBUG)
#define assert(p) if(!(p)){fprintf(stderr,\
"Assertion failed: %s, file %s, line %d\n",\
#p, __FILE__, __LINE__);abort();}
#else
#define assert(p)
#endif

main函数


无参的写法

int main(void)

有参的写法

int main(int argc, char *argv[])
int main(int argc, char **argv)

argc -- 命令行参数总个数,包括 可执行程序名

argv[0] -- 可执行程序名

argv[i] -- 第 i 个参数

例子

# ./a.out Love Live !

该例子中 argc 为4,argv[0]=a.out, argv[1]=Love, argv[2]=Live, argv[3]=!

main函数的位置

C语言规定,main函数是程序的入口。所以不管把main函数放在源程序的任意地方,都是没有错的。

数组 int a[5];


定义一个数组 a 时,编译器根据指定的元素个数和元素的类型分配确定大小的一块内存,并把这块内存的名字命名为 a
名字 a 一旦与这块内存匹配就不能被改变。a[0],a[1]等为 a 的元素,但并非元素的名字。数组的每一个元素都是没有名字的。

&a[0]和&a 的区别(I)

a[0]是一个元素,a 是整个数组,虽然 &a[0] 和 &a 的值一样,但其意义不一样。

前者是数组首元素的首地址,而后者是数组的首地址

数组名 a 作为左值和右值的区别

(1) a 作为右值时其意义与 &a[0] 是一样,代表的是 数组首元素的首地址,而不是数组的首地址。

int *p; p = &a[0]; 或者 int *p; p = a; 两者同意。

(2) a 不能作为左值!只能访问数组的某个元素而无法把数组当一个总体进行访问。

&a[0] 和 &a 的区别(II)

int main()
{
char a[] = {'A','B','C','D'};
char (*p3)[] = &a;
char (*p4)[] = a;
return ;
}

p3 和 p4 都是数组指针,指向的是整个数组。p3 这个定义的“=”号两边的数据类型完全一致,而 p4 这个定义的“=”号两边的数据类型就不一致了。左边的类型是指向整个数组的指针,右边的数据类型是指向单个字符的指针。但由于 &a 和 a 的值一样,而变量作为右值时编译器只是取变量的值,所以运行并没有什么问题。

p3+1 和 p4+1 的值又是多少呢?

C 语言中,当一维数组作为函数参数的时候,编译器总是把它解析成一个指向其首元素首地址的指针。

指针


两个指针指向同一个变量

int *p1,*p2;
int x = ;
p1 = &x;
p2 = p1;

野指针产生的原因

定义指针变量时未初始化;指针释放后之后未置空。free和delete只是把指针所指的内存给释放掉,但并没有把指针本身干掉。此时指针指向的就是“垃圾”内存。释放后的指针应立即将指针置为NULL,防止产生“野指针”。

动态内存的使用

1.使用malloc函数申请内存空间后,要检查指针p是否为NULL

char *p = (char *)malloc(sizeof(char)*LENGTH+1);

if(NULL == p){ }

2.及时为指针p赋初值,防止未初始化内存就去使用

char *p = NULL;

3.申请与释放内存必须配对(malloc-free)

2. 用完指针之后也将指针变量的值设置为 NULL,防止产生“野指针”
free(p);
p = NULL;

C语言笔记(二)的更多相关文章

  1. 嗨翻C语言笔记(二)

    ~a a中所有位都取反 a & b a中的位 与 b中的位 (都为1则1,否则为0) a | b a中的位 或 b中的位 (只要对应位一个位1则为1) a ^ b a中的位 亦或 b中的位 & ...

  2. Go语言学习笔记二: 变量

    Go语言学习笔记二: 变量 今天又学了一招如何查看go的版本的命令:go version.另外上一个笔记中的代码还可以使用go run hello.go来运行,只是这种方式不会生成exe文件. 定义变 ...

  3. #r语言(二)笔记

    #r语言(二)笔记 #早复习 #概述:R是用于统计分析.绘图的语言和操作环境 #对象: #数据类型--统称为对象 #向量(vector):用于存储数值型.字符型或逻辑型数据的一维数组. #定义向量: ...

  4. 手把手和你一起实现一个Web框架实战——EzWeb框架(二)[Go语言笔记]Go项目实战

    手把手和你一起实现一个Web框架实战--EzWeb框架(二)[Go语言笔记]Go项目实战 代码仓库: github gitee 中文注释,非常详尽,可以配合食用 上一篇文章我们实现了框架的雏形,基本地 ...

  5. AJax 学习笔记二(onreadystatechange的作用)

    AJax 学习笔记二(onreadystatechange的作用) 当发送一个请求后,客户端无法确定什么时候会完成这个请求,所以需要用事件机制来捕获请求的状态XMLHttpRequest对象提供了on ...

  6. Swift语言指南(二)--语言基础之注释和分号

    原文:Swift语言指南(二)--语言基础之注释和分号 注释 通过注释向自己的代码中注入不可执行的文本,作为你自己的笔记或提示.Swift编译器运行时会忽略注释. Swift的注释与C语言极其相似,单 ...

  7. NumPy学习笔记 二

    NumPy学习笔记 二 <NumPy学习笔记>系列将记录学习NumPy过程中的动手笔记,前期的参考书是<Python数据分析基础教程 NumPy学习指南>第二版.<数学分 ...

  8. python3.4学习笔记(二) 类型判断,异常处理,终止程序

    python3.4学习笔记(二) 类型判断,异常处理,终止程序,实例代码: #idle中按F5可以运行代码 #引入外部模块 import xxx #random模块,randint(开始数,结束数) ...

  9. Emacs 笔记二

    Emacs 笔记二 Table of Contents 1. 前言 2. emacs基本操作(常用快捷键) 3. emacs模式讲解 4. emacs缓冲区 5. org mode 5.1. 列表 5 ...

随机推荐

  1. Keil-MDK编译完成后代码大小

    Code 代表执行的代码,程序中所有的函数都位于此处. RO-data 代表只读数据,程序中所定义的全局常量数据和字符串都位于此处. RW-data 代表已初始化的读写数据,程序中定义并且初始化的全局 ...

  2. Java Web项目实战第1篇之环境搭建

    写在前面的话 从今天开始一个Java Web实战项目,参考自 http://blog.csdn.net/eson_15/article/details/51277324 这个博客(非常感谢博主的分享精 ...

  3. 创建序列化器,序列化管理器,closureSerializer

    创建序列化器,序列化管理器,closureSerializer //通过反射创建序列化对象 // Create an instance of the class with the given name ...

  4. 【ACM】hdu_zs3_1008_Train Problem I_201308100835

    Train Problem I Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other)Tota ...

  5. sqlserver 字符串函数

    转自:http://www.cnblogs.com/jiajiayuan/archive/2011/06/16/2082488.html 以下所有例子均Studnet表为例:  计算字符串长度len( ...

  6. HDOJ 5417 Victor and Machine 水

    Victor and Machine Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Othe ...

  7. VMware Workstation 集群仲裁磁盘和数据共享磁盘的创建

    近期项目须要对SQL Server建立集群服务,多个SQL Server数据库建立集群服务,对外提供唯一的URL訪问地址.当主节点断电.断网后,通过心跳线将消息传递到备用节点.备用节点在3秒内接管数据 ...

  8. CocoaPods建立私有仓库

    项目管理:CocoaPods建立私有仓库 2015-05-08 10:22 编辑: lansekuangtu 分类:iOS开发 来源:agdsdl 0 6367 CocoaPods项目管理私有仓库 招 ...

  9. C# 操作 INI 自己工作笔记(对文本框的操作)

    using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using Sy ...

  10. 阻塞、非阻塞、同步、异步IO

    阻塞.非阻塞.同步.异步IO http://www.cnblogs.com/yunxitalk/p/9031306.html 介绍 在谈及网络IO的时候总避不开阻塞.非阻塞.同步.异步.IO多路复用. ...