C语言的一些可能犯迷糊的基础

转载 2011年01月10日 17:55:00

1.首先C语言有多少个关键字?答案是32个,也许很少有人蛋疼的数一数。还有define是不是关键字?当然不是。 2.sizeof是什么东西?函数?但是发现 sizeof int 可以编译过去,答案不言而喻,sizeof是运算符,不是函数,当然也是关键字。 但是下面的代码: int a[100]; sizeof(a[100])的值是多少?我的编译器执行后的是4,可能会和你心目中的数不一样。 那么sizeof(a)呢?答案是400! sizeof(&a)呢?答案是4!我是被震撼了。 void fun(int a[100]) { printf("%d",sizeof(a)); } 结果是4!好吧,我已经晕了,说实话我也是不懂这究竟是什么情况。具体的需要大家自己去研究。 3.const修饰的到底是什么? const int *p; // p 可变,p 指向的对象不可变 int const *p; // p 可变,p 指向的对象不可变 int *const p; // p 不可变,p 指向的对象可变 const int *const p; //指针p 和p 指向的对象都不可变 先忽略类型名(编译器解析的时候也是忽略类型名),我们看const 离哪个近。“近水楼台先得月”,离谁近就修饰谁。注:括号括起来的部分表示忽略掉。 const (int) *p; //const 修饰*p,p 是指针,*p 是指针指向的对象,不可变(int) const *p; //const修饰*p,p 是指针,*p 是指针指向的对象,不可变(int) *const p; //const修饰p,p 不可变,p 指向的对象可变 const (int) *const p; //前一个const 修饰*p,后一个const 修饰p,指针p 和p 指向的对象 4.int i=1; int j; j=i+++i+++i++; 首先你可能会问这能编译过去吗?必须能,执行后结果是3,执行后i的值为4;首先,弄明白这个问题,i+++i是怎么运算的? 是(i++)+i呢,还是i+(++i); C 语言有这样一个规则:每一个符号应该包含尽可能多的字符。也就是说,编译器将程序分解成符号的方法是, 从左到右一个一个字符地读入,如果该字符可能组成一个符号,那么再读入下一个字符, 判断已经读入的两个字符组成的字符串是否可能是一个符号的组成部分;如果可能,继续读入下一个字符, 重复上述判断,直到读入的字符组成的字符串已不再可能组成一个有意义的符号。这个处理的策略被称为“贪心法”。 需要注意到是,除了字符串与字符常量,符号的中间不能嵌有空白(空格、制表符、换行符等)。比如:==是单个符号, 而= =是两个等号。这样应该能弄清楚了吧。上面实际上是j=(i++)+(i++)+(i++); 5.大家都知道的,定义一个变量,你要初始化它。因为变量一般在系统中占有一块内存,如果你不 初始化,而且这块内存存储有数据,也许你就要悲剧。 6小小的注意 结构体里面还可以有结构体; register 变量必须是一个单个的值,并且其长度应小于或等于整型的长度。而且register 变量可能 不存放在内存中,所以不能用取址运算符“&”来获取register 变量的地址。 关于switch:如果需要检查同一变量有两种以上的可能值,使用switch语句合适。 如果要检查的是真/假条件,则应该使用if。 7. 关于puts函数和printf函数的一点吹毛求疵 当你需要输出的不包括变量或常量,也就是你只打出一段话 如“Hello World”的时候(说的不专业 ,请见谅),适合使用puts()。虽然printf函数的功能强大,但是开销自然也大。 ps: 可以在puts()中用转义说明符比如/n,但是不能使用转换说明符 如%d 8. 外部变量,有时候叫全局变量,严格的讲外部变量的作用域应该为包含该变量定义的整个源代码文件。 实际编程中很少使用外部变量,是因为使用外部变量违背了模板独立原则,而这种原则是结构化编程的核心。 当函数使用外部变量时,在该函数内使用关键字来“声明”该变量,是个很好的编程惯例。 注意:如果你没有给外部变量初始化(也就是赋值),那么,编译器将会把它初始化为0. 局部变量,作用域为其所在的函数,注意的是编译器不会自动将局部变量初始化为0,所以,使用局部变量之前,必须明确地给它赋值。局部变量默认是动态的,意味着每次调用函数时,都要重新创建变量,而当函数执行完毕,变量将会被释放。 意味着在函数被调用两次之间,函数的动态变量就丢失。 为说明下外部变量,下面给出一段代码: #include int ctr; void print_letter2(void); char letter1 ='x'; char letter2 = '='; int main() { for(ctr=0;ctr<10;ctr++) { printf("%c",letter1); print_letter2(); } return 0; } void print_letter2(void) { for(ctr=0;ctr<2;ctr++) printf("%c",letter2); } 这是个死循环,错误使用外部变量的后果。 8.注意数据溢出现象: int main() { unsigned i; for(i=9;i>=0;i--) { printf("%u/n",i); getch(); } return 0; } i的范围是0到 2的32次方减1 数据发生溢出,造成死循环。

 

#define AAA 1;
#define BBB 2;

int addDe() {
 int re =  AAA * BBB;
 return re;
}
int main(int argc, char* argv[])
{
 int a = addDe();
 return 0;
}

竟然会提示C2100错误。百思不解,用加号+代替*就没有错误,原因何在?

查了一下MSDN:对C2100错误的解释是,*后面是一个非指针变量。大惑,乘号怎么被看成了指针取值?后来一查,原来是一个很简单的错误,在#define的一行结束有“;”。像这种仅仅定义一个常量的的#define语句在一行结束应该是没有分号的。由于宏定义采取的源代码替换,所以到了表达式AAA * BBB;
就被替换成了1;*2;;当然会报非指针变量错误啦。

相关文章推荐

C语言的一些可能犯迷糊的基础

1.首先C语言有多少个关键字?答案是32个,也许很少有人蛋疼的数一数。还有define是不是关键字?当然不是。2.sizeof是什么东西?函数?但是发现 sizeof int 可以编译过去,答案不言而...

20几岁了,别再犯迷糊

  • 2010年03月06日 16:51
  • 673KB
  • 下载

程序设计基础(C语言)课程主页-2016级

时间很快,2016级的小鲜肉们已经在猜测老贺长什么样子了。   从在线作业到翻转课堂,几届的学生跟着我受了不少苦。话虽这么说,并不代表2016级的就要轻松了(老贺虚伪到底!)。不过,苦孩子们,享受吧...

C语言(记录)【内存相关_1:内存基础】

本文是基于嵌入式的C语言 -------------------------------------------------- 首先弄明白程序是什么?计算机为什么需要编程?   编写...

黑马程序员--ios基础--c语言--流程控制

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------  一.流程控制 顺序结构:默认的流程结构。按照书写顺序执行每一条语句。选择结构:对给定的条件...
  • yuanptt
  • yuanptt
  • 2015年05月16日 04:25
  • 208

C语言基础一之预备知识(计算机结构组成、计算机系统组成、进制、原码反码补码)

学习C语言之前,必须先对计算机的一些基本知识有一些了解。包括计算机的体系结构,即计算机又处理器、控制器、内存、输入设备和输出设备组成;计算机分为软件系统和硬件系统;以及二进制、原码反码补码等基础知识。...

C语言基础——数组(及一些常用的函数介绍)

这些内容不是为了给所有人看,是为了自己写的一些总结,以及最近要用C去考试,进行的复习总结,只希望看到的人可以给我补充一下,谢谢。(1)定义一维数组的格式为:数组名[整型常量表达式](2)下标范围必定从...

C语言基础-----二维数组,三维数组

一 二维数组 1.二维数组的定义: 数据类型  数组名[行][列] ={ 数值1,数值2......}; 2.二维数组有几行,就代表有几个一维数组. int a[2][3] = {1,2,3,4...

C语言基础第二篇--基本数据类型

在上一篇文章中我们通过一个经典的C语言入门程序认识了C语言,算是一个小小的入门,也是我对C语言的一次系统的复习,讲的可能不够详细,在接下来的文章中我将尽可能详细的讲述我在学习C语言基础的过程中接触到的...

iOS C语言之基础知识

数据类型 运算符
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C语言的一些可能犯迷糊的基础
举报原因:
原因补充:

(最多只允许输入30个字)