首先声明一下,在我们写的程序中,会使用到一个头文件# 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;

}

打印:

093723177.png


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;

}

093748360.png

程序要注意几点:

  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()

{

inta[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\n

sizeof(&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;

}

输入结果:

093812489.png

为什么会这样呢?大家都知道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个单元后面的空间我们无法访问,但是,这些空间还是实实在在存在的啊!所以还是有地址的!

还有一点要注意,sizeof(a+1)和sizeof(&a+1)的值均为4,大家想想为什么?

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 tocalculate: ");

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;

}

打印:

093839189.png


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;

}

打印:

093856697.png