追风~忆梦

导航

C语言深度学习——第一天

首先声明一下,在我们写的程序中,会使用到一个头文件# include <head.h>

因为,在linux系统编程的时候,会用到很多头文件,为此,我用一个头文件全部包含在一起,头文件内容如下:

# ifndef _OK_

# define _OK_

 

# include <stdio.h>

# include <string.h>

# include <errno.h>

# include <stdlib.h>

# include <time.h>

# include <unistd.h>

# include <sys/types.h>

# include <sys/stat.h>

# include <fcntl.h>

# include <sys/types.h>

# include <dirent.h>

# include <pwd.h>

# include <grp.h>

# include <pthread.h>

# include <semaphore.h>

# include <signal.h>

# include <linux/ipc.h>

# include <sys/socket.h>

# include <netinet/in.h>

# include <arpa/inet.h>

# include <sys/wait.h>

# include <netdb.h>

#define LOG(...) {char _bf[1024];snprintf(_bf,sizeof(_bf),__VA_ARGS__);\

       fprintf(stderr,"%s",_bf);syslog(LOG_ERR,"%s",_bf);}

#endif

编辑好了之后,放到/usr/include/下即可。

 

1.      使用__FILE__,__FUCTION__,__LINE__等宏能自动定位到程序执行到哪一个函数的哪一行,作为一个经典的调试方法,很容易被人忽略,也很重要。如下:

#include <stdio.h>

 

void test()

{

    printf("%s %s %d\n",__FILE__,__FUNCTION__,__LINE__);

}

 

void test_1()

{

    printf("%s %s %d\n",__FILE__,__FUNCTION__,__LINE__);

    test();

}

 

int main()

{

printf("1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = %d\n",1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10);

   printf("%s %s %d\n",__FILE__,__FUNCTION__,__LINE__);

   test_1();

 

   return 0;

}

打印:

 

2.      对于malloc动态内存分配,现在只是给出一个实例,让大家有一个感性的认识,要知道malloc主要用来动态开辟内存空间的,一般malloc都是和free配对的。以后会专门讲解的。下面的一个实例是动态开辟一个一维数组,比较简单。

# include <stdio.h>

# include <stdlib.h>

 

void input(int *array,int len)

{

    int i;

    printf("input %d numbers  ",len);

    for(i=0; i<len; i++)

    {

        setbuf(stdin,NULL);

        scanf("%d",array+i);

    }

}

 

int main()

{

    int n=0,i=0;

    int *a, array[n];

 

    printf("input characters ");

    scanf("%d",&n);

 

    a = (int *)malloc(n*sizeof(int));

    input(a,n);

    printf("the characters you input are ");

    for(i=0; i<n; i++)

        printf("%d ",a[i]);

    printf("\n");

 

    printf("a = %p,array = %p\n",a,array);

   

    free(a);

        a = NULL;

 

    return 0;

}

程序要注意几点:

  1. C99标准中,准许使用下面的做法,但是不推荐

int n = 0;

scanf(“%d”,&n);

int ch[n] ;

  1. 在两次连着输入的时候,注意清除键盘缓存,在linux下可以用setbuf(),Windows下可以用fflush()等,关于清除缓存,以后会专门讲解。
  2. 再次强调,malloc一定要和free配对使用,如果申请的空间不释放,一次两次也许不会有什么错误,申请多了就会发生内存泄漏,系统崩溃等严重问题,所以不要抱有侥幸心理。释放之后,a就是一个野指针了,一般而言,要将其赋为空,这是一个很好的习惯,希望大家坚持。

3.      大家看看下面的程序的输出结果是什么?

# include <stdio.h>

int main()

{

     int a[5]={0x10111213,0x20212223,0x30313233,0x40414243,0x50515253};

     printf("a[5]={0x10111213,0x20212223,0x30313233,0x40414243,0x50515253}");

     printf("\na = %p\n&a = %p\n",a,&a);

     printf("a+1 = %p\n&a+1 = %p\n",a+1,&a+1);

     printf("&a[0] = %p\n&a[0]+1 = %p\n",&a[0],&a[0]+1);

     printf("\nsizeof(a) = %d\nsizeof(&a) = %d\n",sizeof(a),sizeof(&a));

     printf("sizeof(&a[0]) = %d\nsizeof(&a[5]) = %d\n",sizeof(&a[0]),sizeof(&a[5]));

     printf("sizeof(&a[10]) = %d\n

     sizeof(a[5]) = %d\n\n",sizeof(&a[10]),sizeof(a[5]));  

     return 0;

}

输入结果:

为什么会这样呢?大家都知道a是一个数组名,准确的讲,a是该数组首元素的地址,而&a是什么呢?&a整个数组的地址。就像一栋房子一楼的门卫室,如果门卫室坐落在***地方,则这个***既是门卫室的地址,也是整栋大楼的地址,它们的值相等,但是表示的意思不一样,这就解释了为什么a&a都等于0xbff7aadc,而sizeof(a)等于20sizeof(&a)却等于4,因为&a是一个指针变量,32位机下的都是占4个字节,由此,我们可以推出对于一位数组buf[],我们想求出里面元素的个数可以使用sizeof(buf) / sizeof(buf[0])

对于a+1&a+1a+1则是第二个元素即a[1]的地址,这里的1表示一个数组单元,0xbff7aadc+4=0xbff7aae0&a+1则是a[4]的下一个地址,此时的1表示的整个数组单元, 0xbff7aadc+4*5=0xbff7aaf0

大家会有疑问,我们数组是a[5],应该最大为a[4],怎么会有a[5]a[10]啊?为什么没有产生溢出?因为在整个数组中我们只是申请了5个单元,虽然这5个单元后面的空间我们无法访问,但是,这些空间还是实实在在存在的啊!所以还是有地址的!

4.      下面的程序是实现简单的求mn之间的素数,大家看看吧!

# include <stdio.h>

int prime(int n)

{

     int i,j;

    for(i=2; i<=n; i++)

        if(n%i==0)

            break;

        if(i==n)

            return 1;

        else

            return 0;

}

 

int main()

{

    int i,j,m,n;

    printf("Please input the Prime min and max limitation you want to calculate: ");

    scanf("%d,%d",&m,&n);

    printf("The Prime of %d to %d limitation are ",m,n);

    for(i=m; i<=n; i++)

        if(prime(i))

            printf("%d ",i);

    printf("\n");

    return 0;

}

打印

 

5.      大家说说,浮点数能进行自增和自减运算吗?答案是肯定的,不信?我们做个实例测试一下。

# include <head.h>

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

{

        float i = 1.0;

        double j = 2.0;

        printf("i=1.0,++i = %f,j-- = %f\n",++i,j--);

 

        return 0;

}

打印:

posted on 2013-12-23 14:01  追风~忆梦  阅读(468)  评论(0编辑  收藏  举报