文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>C语言一些细节注意(源码+解释)

C语言一些细节注意(源码+解释)

时间:2010-03-11  来源:dzt_tomdu

最近可能要回归底层开发设计,所以又看了看C的一些东西。顺便对一些问题进行了代码确认。现将代码贴出,希望对各位网友有所帮助。 /******************************************************************************
*                                                                            **
*只是为了测试,没有按照什么规范写。代码风格比较烂。哈哈哈哈,大家见谅了。^O^ **
*                                                                            **
*******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SQR(x)      ((x) * (x))     //注意此处一定要把x括起来,避免传入的值有括号或者计算
#define TSqr(x)     printf("The square of "#x" is %d\n",((x) * (x)))
#define __V         1.0.0 static int j;
/*
    fun1 fun2是测试static修饰符的作用的。
*/
int fun1()
{
 static int i = 0;
 i++;
 printf("i=%d ",i);
}
int fun2()
{
 j = 0;
 j++;
 printf("j=%d ",j);
}
/*
    fun3测试数组的传递。数组传递的是一个地址而不是数组的值。
    而且传递的是实参的一个拷贝,而不是实参本身
*/
int fun3(char a[],int b[])
{
    printf("\nInput parameter(a) size is %d",sizeof(a));        //所以此处的值在32位机器上是4
    printf("\nInput parameter(b) size is %d",sizeof(b));        //所以此处的值在32位机器上是4
    printf("\nInput parameter(a[2]) value is %c",a[2]);
    printf("\nInput parameter(b[2]) value is %d",b[2]);         //数组的第3个元素的值
   
    return;
}
/*
    fun4 测试负数整除及取余的操作。
         测试C语言的几个全局宏定义,这三个宏定义对于写日志文件(log)很有用处
*/
int fun4()
{
    printf("A==%d B==%d",(-3)/2,(-3)%2);         //这个地方都是-1
   
    printf("\nFile:%s ",__FILE__);                  
    printf("\nLine:%d ",__LINE__);
    printf("\nDate:%s ",(char*)__DATE__);
}
/*
*   fun5测试数组的相关注意事项,及数组参数传递
*/
int fun5()
{
    int a[3][2] = {(0,1),(2,3),(4,5)};
    int b[3][2] = {{0,1},{2,3},{4,5}};   
    int c[5] = {0,1,2,3,4};
   
    char d[5] = "abcde";
   
    int *p;
    int *t;
   
    p=a[0];
    t=b[0];
   
    printf("\nFalse:%d\n True:%d",p[0],t[0]);        //p[0]为1,因为初始化数组是用的是小括号。t[0]是0因为用的是花括号。
   
    printf("\n");
    fun3(d,c);                                       //传递地址,数组c的一个拷贝
   
}
/*
 * 测试结构体内部指针内存分配
 */
int fun6()
{
    struct sctTest
    {
        char *name;
        int nSex;
    };
   
    //定义一个结构体指针
    struct sctTest *pTst;
    struct sctTest Tst;
   
    //将结构体变量值初始化为0,不过我通过单步调试发现不初始化,结构体内部变量的值也是0,
    //但是好的书写规范建议对变量还是进行初始化的好。因为局部变量的值不初始化其值是不定的。
    memset(&pTst,0,sizeof(struct sctTest));
    memset(&Tst,0,sizeof(struct sctTest));
   
    //初始化结构体指针,分配内存.如果不要这句程序会报错。内存溢出。因为pTst是指针,指针没有合法
    //的内存地址指向,导致野指针存在
    pTst = (struct sctTest*)malloc(sizeof(struct sctTest));
       
    //初始化结构体中指针name。如果不要这句程序会报错。内存溢出。因为name指针没有合法
    //的内存地址指向
    if(NULL == pTst)
    {
        return;
    }
    pTst->name = (char*)malloc(sizeof(char *));
   
    Tst.name = (char *)malloc(sizeof(char *));
   
    if(NULL == pTst->name || NULL == Tst.name)
    {
        return;
    }
    strcpy(pTst->name,"BeiJing");
    strcpy(Tst.name,"chiping");
    printf("The name of pTst is %s\n",pTst->name);
    printf("The name of Tst is %s\n",Tst.name);
   
    //释放,避免野指针出现,避免内存泄露
    free(pTst);
    free(pTst->name);
    free(Tst.name);
   
    pTst=NULL;
           
    return 0;
}
/*
 * fun7 测试为什么要在释放内存后将指针指向NULL(哈哈哈,栓野狗的桩子^_^)
 */
int fun7()
{
    printf("\nFun7 start\n");
    char *pChr = (char *)malloc(sizeof(char *));
   
    if(NULL == pChr)
    {
        return -1;  
    }
   
    strcpy(pChr,"abcdefg");
    printf("\nString is %s\n &%x",pChr,&pChr);
   
    free(pChr);
   
    //如果不讲pChr指针指向NULL,pChr依然保存上次申请地址时的地址信息。free只是将pChr指针不再指向
    //申请的内存地址,不再拥有该内存地址的使用权,但是内容却没有改变,所以要指向NULL
    //pChr=NULL;
    //char *tt = (char *)malloc(10);
    //printf("\ntt address is %x\n",&tt);
    /*如果不指向NULL,那么下边这段代码是要出问题的。因为pChr此时不是NULL,但是他没有
     *可用的内存了,可用内存被free掉了。所以strcpy时会内存溢出(^_^出问题了,我在gcc环境下
     *free掉后下边的代码照常执行,高手看看啥原因呀?这个地方如果是复杂程序有可能会失败。此处的pChr
     *已经是野指针了,因为free已经告诉操作系统这块地址pChr不用了,你可以用作其他用途,但是你还用
     *那么就是在操作野指针,有时可能不会出错,但是程序不知道什么时候就出错了。这种错误是相当危险了,出现问题后
     *你会很难定位问题出现的原因。比如,在调用fun7的时候你循环调用10000次,你就会发现你的程序会在某次
     *循环后出错。)
     */
    if(NULL != pChr)
    {
        strcpy(pChr,"aaaaaaaaaaaaaa");
        printf("\nString2 is %s\n &%x",pChr,&pChr);
    }
   
    return 0;
   
}
int main()
{
    int k = 0;
    //以下for循环测试static修饰符
    for(k = 0; k < 10; k++)
    {
         fun1();
  
         fun2();
    }
    printf("\n");
 
    //测试不同情况下sizeof,切忌sizeof是保留字而不是函数。
    printf("sizeof->(int):%d (k):%d k:%d",sizeof(int),sizeof(k),sizeof k);
    int *p;
    
    //测试指针变量的大小,指针变量的大小是指针存储数据类型的大小
    printf("\nint(p) size is %d",sizeof(p));
 
    char *chrP=NULL;
    printf("\nchar(p) size is %d",sizeof(chrP));
    chrP = (char *)malloc(10*sizeof(char *));
    //对指针一定要做判空操作,因为内存申请有可能申请失败
    if(NULL != chrP)
    {
        strcpy(chrP,"abc");
    }
   
    printf("\nchar(Assignment p) size is %d",sizeof(chrP));
    printf("\nchar(Assignment p) length is %d",strlen(chrP));
    void *vP=NULL;
    printf("\nvoid(p) size is %d",sizeof(vP));
   
    free(chrP);
    free(vP);
    chrP = NULL;
    vP = NULL;
  
    //通过以上测试确定指针类型的sizeof的值为4。strlen则是指针
    //实际指向的地址空间存储的数据的长度(不包括结束符)
   
     
    //#ifdef __V
    #pragma message("__V is defined");
    //#endif
    int a[4];
    memset(a,0,sizeof(a));
 
    /*测试数组的首地址及首元素的首地址
     *a是整个数组的首元素的首地址,&a是整个数组的首地址
     *注意&a+1,这里的1是4*sizeof(int)
     *对指针进行加1 操作,得到的是下一个元素的地址,而不是原有地址值直接加1。所以,
     *一个类型为T的指针的移动,以sizeof(T)  为移动单位。
     */
    printf("\n&a size=%d &a[0] size=%d ",sizeof(&a),sizeof(&a[0]));
    printf("\n&a=%d &a[0]%d a=%d &a+1=%d",&a,&a[0],a,&a+1);
    //int iRef = fun3(a);     //测试有符号与无符号数据的计算
    int i = -20;
    unsigned int j = 10;
 
    printf("\nint + unsigned = %d ",i+j);
    //测试标识符(//)
    char *chrContext="aaaaaaa   //bbbbbbbbbbb";
    printf("\n// in string :%s",chrContext);
   
    printf("\n");
    //测试标识符(#)
    TSqr(10);
   
    //测试标识符(##)没有搞定,待高手解决
    //XNAME(8);
   
    fun4();
    printf("\n");     //测试宏定义注意事项
    printf("SQR: %d\n",SQR(10));
 
    fun5();
 
    printf("\n");
 
    fun6();
    int tt=0;
 
    //for(tt=0;tt<10000;tt++)
    //{
    //    printf("\ncount=%d\n",tt);
          fun7();
    //}
 
    return 0;
}
相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载