C语言知识体系


 一.选择结构程序设计以及循环结构设计
    1.if语句的使用
    1).bool变量与“零值”比较
    bool i = FALSE;
    那么下面初始化什么比较好?
 
 
?
1
2
3
if ( i == 0 );  if (i == 1 // 1
  if ( i == TURE); if ( i == FALSE);  //2
  if (i); if (!i);  //3

 

    注意:大家知道if语句是靠其后面括号里表达式的值来进行分支跳转。表达式为真,则执行if语句后面紧跟的代码;否则不执行。那显然,第三组写法很好。不会引起误会,也不会因为TRUE,FALSE的不同定义值而出错。
    当然,还有float变量和“零值”比较。指针变量与“零值”比较。大家可以自己研究。我在这里就不再讲述了。
    2.while循环使用
    1).讲述一个例子来剖析一下吧
    
 
   
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include
  
int main()
{
     int a = 1 ;
     int b = 2 ;
     int c = 2 ;
     int t;
     while (a < b < c)
     {
         t = a;
         a = b;
         b = t;
         c--;
     }
     printf( "%d %d" , a, c);
     system( "pause" );
     return 0 ;
}

 

    分析一下结果会是什么?a的值为1,c的值为0;while循环也关注的是括号里面的值是否为真,那么a<b<c怎么分析,首先第一次进行判断,a为1,b为2,a<b为真,那么这个表达式的值为真(真为1,假为0),那么1<c,进入循环,同理进行第二次循环,最后算出结果。while循环需要注意的就是括号中的表达式中的值,如果写成while(1),那就是无限循环,读者可以尝试在while(1)中动态开辟内存,试试我说的话对不对。当然前提也可以使用break语句跳出或者return语句跳出循环。< div="">
    3.for循环的使用
    同样用一个例子来分析一下
 
   
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include
     
    int main()
    {
        int i = 0 ;
        int arr[ 10 ] = { 0 };
        for (i = 0 ; i < 10 ; i++)
        {
            arr[i] = i;
        }
        for (i = 0 ; i < 10 ; i++)
        {
            printf( "%d\n" , arr[i]);
        }
            system( "pause" );
            return 0 ;
    }

 

    当然这个程序是非常简单,但足以说明问题。当i = 10的时候会跳出循环。那么就很简单明了了。当然for循环也可以用while循环改写。
     二.数组
    数组是储存同一数据类型的一组有序的数据的集合。
    数组中需要注意的点:
    1.数组用循环语句赋值。同样是上面的for循环,可以自己试试将条件 i<10改为 i<11试试。程序会无条件的奔溃。因为你操作越界了,访问了不属于你自己的内存。
    2.数组下标的操作。记住一点的就是,数组的下标是从0开始,并不是1!!!
    3.数组和逗号表达式一起迷惑你。
 
         
 
?
1
2
3
4
5
6
7
8
9
10
#include
   
  int main()
  {
      int a[ 3 ][ 2 ] = { ( 0 , 1 ), ( 2 , 3 ), ( 4 , 5 ) };
      int *p = a[ 0 ];
      printf( "%d" , p[ 0 ]);
      system( "pause" );
      return 0 ;
  }

 

    这个时候的p[0]等于1;为什么,不是应该是0?这就考到了逗号表达式,逗号表达式最后一个值才是整个表达式的值,那么上面的代码就变成了 int a[3][2] = {1,3,5};如果这样说,你是不是就会做对呢?
    4.二维数组在内存中的存储
    假如二维数组
    
 
?
1
int arr[ 3 ][ 3 ] = { 0 };

 

    二维数组在内存中存储是线性的。我们可以用一维数组的方式来理解二维数组,上述代码代表的二维数组有三个元素,arr[0],arr[1],arr[2],同时每一个元素分别有三个元素,arr[0][0],arr[0][1],arr[0][2]...,那么可以这样理解arr[0],arr[1],arr[2],就是一维数组的数组名,只不过这三个一维数组是有联系的并且在内存中是连续开辟的。
    同理我们可以推到三维数组直到n维数组。只要你有时间并且有毅力和决心(意义不大)。哈哈!!
    5.字符数组
    字符数组的赋值方式,为什么要提字符数组的赋值方式,本人认为这和字符串的操作息息相关,看看两种不同的赋值方式。
    1).
 
?
1
char arr[]={ 'i' , ' ' , 'a' , 'm' , ' ' , 'h' , 'a' , 'c' , 'k' , 'e' , 'r' };

 

    可以预见的是,没有‘\0’;那么这个字符数组所储存的字符串是不会使用一系列的字符串操作函数。如果对常见的字符串操作函数不太了解,那么访问下面的链接,http://10799170.blog.51cto.com/10789170/1715083 帮助你了解常见的字符串操作函数的实现与注意的事项。言归正传,第二种赋值方式。
    2).
 
    char arr[] = "i am hacker";
    这种赋值方式,是最常见也是经的起考验,建议大家就这样使用字符数组的赋值。这种赋值方式不会丢掉“\0”。那么,问题来了,可不可以这样赋值?
 
  
?
1
2
char arr[] = { "i am hacker" };
   char arr[] { = "i am hacker" };

 

    答案是肯定的,有兴趣的读者可以在《c语言深度剖析》第二章第6小节看到。
    6.总结一下:
    1).自己给数组在内存中赋值的时候,千万注意内存越界的问题。
    2).数组的下标操作。
    3).字符数组的“\0”。
    4).二维数组的赋值方式,理解方式以及使用方式。
     三.指针
    指针是地址。我在初学指针的时候,总是分不清楚,指针和指针变量和它指向的地址中的内容的区别,所幸,我在钻研了一下午理解了指针这个东西。得益于一本叫做《c和指针》的书,里面讲述的清楚易懂。
    1.一级指针
    定义一个一级指针
1
        int *p = NULL;
    首先要说的是,指针就是地址,指针变量就是用来保存指针指向的那块空间的地址,“*”就是打开这块内存的钥匙。其次,指针的定义和赋值是两码事,不可以混为一谈。最后我也曾经写过自己对指针,数组指针的理解。读者有兴趣可以打开下面的链接
 
    1).指针的笑话(在 vc6.0中实现)
    
 
?
1
2
3
int *p = ( int *)ox12ff7c;  //这个地址必须是内存开始给变量分配地址的第一个,要不是                                   //不会有作用!
    *p = NULL;
    p = NULL;

 

    读者可以自己试试结果是什么。
    2).谈谈指针的安全
    指针是可以指向内存中的任何地址的,但是在一个程序中,总是只有自己的栈帧,或者储存在静态去和堆上的内存。如果一不小心访问到不属于自己的内存,并改掉其中的值。对于一个大型程序来说,调试都是一个非常庞大的工作。所以,在使用指针的时候千万要小心。杜绝野指针!!
    3).const和assert修饰指针
    不需要修改指针指向的值,请必须加上const修饰
    
 
?
1
2
3
4
const int *p;
int const *p;
int * const p;
const int * const p;

 

    读者可以尝试着分析上面的语句代表着什么。
    assert只在debug版本生效,在release版本没有意义。在debug版本可以帮助我们检验指针的有效性。大公司面试的时候很注重这一定。
    自己在学习的时候看的书是《c语言深度剖析》和《c和指针》。读者可以自己进一步了解。
     四.内存操作
    说到内存操作,不得不提到栈帧。读者可以参考我原来写过的一片博文 附上url
    http://10799170.blog.51cto.com/10789170/1715186 
    那么我们在这里就主要讨论讨论malloc开辟内存时应该注意的问题。
    1).动态开辟内存后,需要判断内存是否开辟成功。
    如果内存没有开辟成功,我们直接使用会造成访问越界;
    2).在使用完成后必须使用free函数释放掉内存,其原理是将指针与内存切断联系。
    会造成内存泄漏。很危险!
    3).使用完成后指针应赋为NULL;杜绝野指针。
    没有及时将指针赋值为NULL,指针会指向“垃圾”内存!
    五.函数
    函数这一部分,本来是不愿意拿出来说的,毕竟每一个学习c语言的人,几乎都在写函数。那么我们就总结一下函数的好处吧。
    1).降低复杂性
    2).避免重复代码
    3).限制改动带来的影响。
    4).隐含顺序
    5).改进性能
    6).进行集中控制
    读者需要了解请参照《c语言深度剖析》。
  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值