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

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<stdio.h>

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  数据发生溢出,造成死循环。

 

ps:其中很多知识点都是来自《C语言深度剖析》这本书,C语言的一些细节真的是让人很难把握,指针就是一个,现在是入门级,希望能和大家共同学习,共同进步! 

  • 1
    点赞
  • 76
    收藏
    觉得还不错? 一键收藏
  • 51
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 51
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值