C语言基础

前言

大一学习的 C 语言,现在回过头来发现已经忘的差不多了,正好趁着这个机会复习整理下,本文的目的偏向于整理备忘,讲解的部分会占很少。

目录及相关习题参考 《C程序设计(第四版)》谭浩强

1 算法表示

1.1 常见流程图

当型循环

直到型循环

1.2 NS 流程图

伪代码表示

2 数据类型

2.1 整型数据

(1)普通整型(int),存储单元中使用反码形式存放
2字节 -32768~32767 或 4字节 -2147483648~2147483647

(2)短整型(short int 或 short),同反码存储
vc6.0 int 4 字节,short int 2 字节

(3)长整型(long int 或 long)
vc6.0 long 4 字节

(4)双长整型(long long int)
一般 8 字节

有符号数据 0 正 1 负,默认为有符号数据

2.2 字符型数据

一字节

char c = '?';

注意

'A' 表示一个字符
"A" 表示一个字符串,后面还有一个 \0

2.3 浮点型数据

单精度浮点型(float),双精度浮点型(double),长双精度(long double)

2.4 赋值过程中类型转换

因为 C 是强类型语言,如赋值语句两侧变量类型不相同则会进行转换

注意

printf("%f\n", 1/3);    //输出 0.000000,因为 1/3 结果为整型 0

printf("%f\n", 1.0/3);  //正确方法,输出 0.333333

2.5 强制类型转换

(double)a
(int)(x+y)
int(x)+y    //只将 x 转为整型

3 C 语言注释

两种注释方式

  • 块注释(block comment):以 /* 开始,*/ 结束
  • 行注释(line comment):以 // 开始

4 数据的输入输出

4.1 printf 输出数据

4.1.1 一般格式

语法:printf(格式字符, 输出变量);

example: printf("%d,%c\n",i,c); // 注意是双引号

4.1.2 格式字符

修饰字符

%m.nf   指定数据的宽度和小数位数,m 包含小数点

printf("%6.3f\n", 1.0/3);   //输出 0.333
printf("%06.3f\n", 1.0/3);  //输出00.333    宽度不够 0 凑位

4.2 scanf 输入数据

4.2.1 一般形式

语法:scanf(格式字符, 地址表列);

example: scanf("a=%f,b=%f,c=%f", &a, &b, &c); //1. 双引号 2. 注意是地址 &a

4.2.2 格式字符

注意

(1)
double 类型数据
scanf 时格式字符使用 %lf
printf 时格式字符使用 %f

(2)
scanf 时,遇空格,回车,tab或遇到非法字符(如输入数字时遇到字符)则认为该数据结束

4.3 字符数据的输入输出

putchar 输出一个字符

putchar(c);

getchar 输入一个字符

c = getchar();

getchar 还可以获取屏幕上无法显示的字符,如控制字符

4.4 习题(第三章)

//math 库 pow 函数应用
#include <stdio.h>
#include <math.h>

int main(){
	float r, p;
	int n;
	r = 0.09;
	n = 10;
	p = pow((1+r), n);
	printf("%f\n", p);
	return 0;
}

//利息计算
#include <stdio.h>
#include <math.h>

int main(){
	double P1, P2, P3, P4, P5;
	
	P1 = 1000*(1+5*0.0585);
	P2 = (1000*(1+2*0.0468))*(1+3*0.054);
	P3 = (1000*(1+3*0.054))*(1+2*0.0468);
	P4 = 1000*pow(1+0.0414, 5);
	P5 = 1000*pow(1+0.0072/4, 5*4);
	
	printf("%f\n%f\n%f\n%f\n%f\n", P1, P2, P3, P4, P5);
	return 0;
}

注意

第二问,char 存储为一字节,按补码形式存储

注意

scanf 时,遇空格,回车,tab或遇到非法字符(如输入数字时遇到字符)则认为该数据结束

所以 71.82 和 Aa 之间不应有空格或回车

5 选择结构程序设计

5.1 if 语句实现选择结构

一般有两种形式

(1)

if(a>b){
    c = a;
}
else{
    c = b;
}

(2)

if(number>500){
    cost = 0.15;
}
else if(number>300){
    cost = 0.075;
}
else{
    cost = 0;
}

注意

// 无花括号时,if 条件为真,只会执行之后的一条语句
#include <stdio.h>
 
int main()
{
    if (true)
    {
        printf("11111111111\n");  // 这两条都会打印
        printf("11111111111\n");
    }
 
    if (false)
        printf("11111111111\n"); // 只有这一条不会打印
        printf("22222222222\n"); // 以下两条都会打印
        printf("22222222222\n");
    return 0;
}

5.2 关系运算符及优先次序


优先次序

5.3 逻辑运算符及优先次序


优先次序,!(非)最高

5.4 条件表达式

ch=(ch>='A' && ch<='Z')?(ch+32):ch;

5.5 switch 语句

switch(grade){
    case 'A': printf("85~100\n");break;
    case 'B': printf("70~84\n");break;
    case 'C': printf("60~69\n");break;
    case 'D': printf("<60\n");break;
    default: printf("enter datda error!\n");
}

//注意每次需要用 break 跳出语句,不然后一直往下运行

5.6 习题(第四章)

// (1)判断哪个等级方法(2)60一下输出E
#include <stdio.h>
int main()
  { float score;
    char grade;
    printf("请输入学生成绩:");
    scanf("%f",&score);
    while (score>100||score<0)
	{printf("\n 输入有误,请重输");
	scanf("%f",&score);
	}
    switch((int)(score/10))
       {case 10:
	case 9: grade='A';break;
	case 8: grade='B';break;
	case 7: grade='C';break;
	case 6: grade='D';break;
	case 5:
	case 4:
	case 3:
	case 2:
	case 1:
	case 0: grade='E';
	}
    printf("成绩是 %5.1f,相应的等级是%c\n ",score,grade);
	return 0;
}

#include <stdio.h>
#include <math.h>
int main()
{
  int num,indiv,ten,hundred,thousand,ten_thousand,place;      //分别代表个位,十位,百位,千位,万位和位数 
  printf("请输入一个整数(0-99999):");
  scanf("%d",&num);
  if (num>9999)
       place=5;
  else  if (num>999)
       place=4;
  else  if (num>99)
       place=3;
  else  if (num>9)
       place=2;
  else place=1;
  printf("位数:%d\n",place);
  printf("每位数字为:");
  ten_thousand=num/10000;
  thousand=(int)(num-ten_thousand*10000)/1000;
  hundred=(int)(num-ten_thousand*10000-thousand*1000)/100;
  ten=(int)(num-ten_thousand*10000-thousand*1000-hundred*100)/10;
  indiv=(int)(num-ten_thousand*10000-thousand*1000-hundred*100-ten*10);
  switch(place)
    {case 5:printf("%d,%d,%d,%d,%d",ten_thousand,thousand,hundred,ten,indiv);
	    printf("\n反序数字为:");
	    printf("%d%d%d%d%d\n",indiv,ten,hundred,thousand,ten_thousand);
	    break;
     case 4:printf("%d,%d,%d,%d",thousand,hundred,ten,indiv);
	    printf("\n反序数字为:");
	    printf("%d%d%d%d\n",indiv,ten,hundred,thousand);
	    break;
     case 3:printf("%d,%d,%d",hundred,ten,indiv);
	    printf("\n反序数字为:");
	    printf("%d%d%d\n",indiv,ten,hundred);
	    break;
     case 2:printf("%d,%d",ten,indiv);
	    printf("\n反序数字为:");
	    printf("%d%d\n",indiv,ten);
	    break;
     case 1:printf("%d",indiv);
	    printf("\n反序数字为:");
	    printf("%d\n",indiv);
	    break;
      }
  return 0;
 }


顺序排序

#include <stdio.h>
int main()
 {int  t,a,b,c,d;
  printf("请输入四个数:");
  scanf("%d,%d,%d,%d",&a,&b,&c,&d);
  printf("a=%d,b=%d,c=%d,d=%d\n",a,b,c,d);
  if (a>b)
    { t=a;a=b;b=t;}
  if (a>c)
    { t=a;a=c;c=t;}
  if (a>d)
    { t=a;a=d;d=t;}
  if (b>c)
    { t=b;b=c;c=t;}
  if (b>d)
    { t=b;b=d;d=t;}
  if (c>d)
    { t=c;c=d;d=t;}
  printf("排序结果如下: \n");
  printf("%d  %d  %d  %d  \n"   ,a,b,c,d);
  return 0;
 }

6 循环结构程序设计

6.1 while 实现循环

当型循环

while(i<=100){
    sum=sum+i;
    i++;
}

6.2 do……while 实现循环

直到型循环

do{
    printf("%d", i++);
}
while(i<=100);

6.3 for 实现循环

for(i=1;i<=100;i++){
    printf("%d", i);
}

6.4 习题(第五章)

重点

// 求解最小公倍数和最大公约数
// 求最大公约数: 辗转相除法(欧几里得算法)
// 两数乘积等于最大公约数与最小公倍数的乘积
#include <stdio.h>
int main(){
	int m,n,temp,r,p;
	printf("请输入两个正整数 m,n:");
	scanf("%d%d", &m, &n);
	if(m<n){
		temp=m;
		m=n;
		n=temp;
	}
	p=m*n;
	while(n!=0){
		r=m%n;
		m=n;
		n=r;
	}
	printf("最大公约数是: %d\n", m);
	printf("最小公倍数是: %d\n", p/m);
	return 0;
}

// if((c=getchar())!='\n')
#include <stdio.h>
int main()
 {
  char c;
  int letters=0,space=0,digit=0,other=0;
  printf("请输入一行字符:\n");
  while((c=getchar())!='\n')
   {
     if (c>='a' && c<='z' || c>='A' && c<='Z')
    	letters++;
     else if (c==' ')
	    space++;
     else if (c>='0' && c<='9')
	    digit++;
     else
	    other++;
    }
   printf("字母数:%d\n空格数:%d\n数字数:%d\n其它字符数:%d\n",letters,space,digit,other);
   return 0;
  }

//注意an的求法
#include <stdio.h>
int main(){
	int a,n,i=1,result=0,an=0;
	printf("a,n:");
	scanf("%d,%d",&a,&n);
	while(i<=n){
		an=an+a;
		printf("%d\n",an);
		result=result+an;
		a=a*10;
		i++;
	}
	printf("a+aa+aaa+ …=%d\n",result);
	return 0;
}

#include <stdio.h>
int main()

 {double s=0,t=1;
  int n;
  for (n=1;n<=20;n++)
  {
   t=t*n;
   s=s+t;
  }
  printf("1!+2!+...+20!=%22.15e\n",s);
  return 0;
}

重点

//水仙花数
#include <stdio.h>
#include <math.h>
int main(){
	int i,ge,shi,bai;
	for(i=100;i<1000;i++){
		ge=i%10;
		shi=(i%100)/10;
		bai=i/100;
		if(i==(pow(ge,3)+pow(shi,3)+pow(bai,3))){
			printf("%d ",i);
		}
	}
	return 0;
}

//100以内的完数
#include <stdio.h>
int main()
 {int m,s,i;
  for (m=2;m<1000;m++)
    {s=0;
     for (i=1;i<m;i++)
       if ((m%i)==0) s=s+i;
     if(s==m)
      {printf("%d,its factors are ",m);
       for (i=1;i<m;i++)
	 if (m%i==0)  printf("%d ",i);
       printf("\n");
	   }
    }
  return 0;
 }

//斐波那契数列变形
#include <stdio.h> 
int main()
 {
  int i,n=20;
  double a=2,b=1,s=0,t;
  for (i=1;i<=n;i++)
   {
   s=s+a/b;
   t=a,
   a=a+b,
   b=t;
   }
   printf("sum=%16.10f\n",s);
   return 0;
   }

//牛顿迭代法求平方根
//初值x0=a/2
//注意do……while循环while的条件
#include <stdio.h>
 #include <math.h>
int main()
 {
  float a,x0,x1;
  printf("enter a positive number:");
  scanf("%f",&a);
  x0=a/2;
  x1=(x0+a/x0)/2;
  do
   {x0=x1;
    x1=(x0+a/x0)/2;
   }while(fabs(x0-x1)>=1e-5);
  printf("The square root of %5.2f  is %8.5f\n",a,x1);
  return 0;
 }

重点

//图形输出问题
//分成两部分来看,找每一行空格,*和行号的规律
//注意输出一行后记得输出\n
#include <stdio.h>
int main(){
  int i,j,k;
  for(k=1;k<=4;k++){
  	for(i=1;i<=4-k;i++){
  		printf(" ");
	  }
	for(j=1;j<=2*k-1;j++){
		printf("*");
	}
	printf("\n");
  }
  for(k=1;k<=3;k++){
  	for(i=1;i<=k;i++){
  		printf(" ");
	}
	for(j=1;j<=2*(3-k)+1;j++){
		printf("*");
	}
	printf("\n");
  }
  return 0;
 }


//比赛排序问题
//先逻辑图,判断出正确结果
//编程使用假设的方法,三层循环,判断符合条件的情况
#include <stdio.h>
int main(){
  char i,j,k;
  for(i='X';i<='Z';i++){
  	for(j='X';j<='Z';j++){
  		if(i!=j){
  			for(k='X';k<='Z';k++){
  				if(k!=i&&k!=j){
  					if(i!='X'&&k!='X'&&k!='Z'){
  						printf("A-%c,B-%c,C-%c\n",i,j,k);
					  }
				  } 
			  }
		  }
	  }
  }
  return 0;
 }

7 数组

7.1 一维数组

7.1.1定义方法
int a[10];

注意

(1)a[10] 下标从0开始到9

(2)
int a[3+5]; // 合法

scanf("%d", &n);
int a[n];

int a[n] 是不合法的,即c语言不允许对数组的大小作动态定义

(3)
void func(int n){
    int a[2*n];
}

为函数参数时可以,这种情况称为“可变长数组”

(4)为static存储方式时,不能用“可变长数组”
static int a[2*n]; //非法
7.1.2 引用
a[0] 或 a[2*3]
7.1.3 初始化
  1. 全部初始化
int a[10]={0,1,2,3,4,5,6,7,8,9};    //注意大括号,逗号
  1. 只给一部分元素赋值
int a[10]={0,1,2,3,4};  // 前5个赋初值,后5个赋初值0
  1. 全部赋初值0可写成
int a[10]={0};
  1. 可以不指定数组长度
int a[]={0,1,2,3,4};    //数组长度自动为5

7.2 二维数组

7.2.1 定义方法
float a[3][4];  //可以理解成3行4列矩阵,内存中先顺序存储第一行,再存储第二行
7.2.2 引用
int a[3][4];    //定义3×4二维数组
a[3][4]=3;  //不存在a[3][4]元素

注意定义和数组下标范围的区别
7.2.3 初始化
  1. 分别赋初值
int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}}; 大括号中嵌套大括号
  1. 可写在一个大括号内
int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};


4.

7.3 字符数组

char c[10]="China";
7.3.1 字符串处理函数

#include <string.h>

  1. puts
char str[]="China\nBeijing"
puts(str);
  1. gets
gets(str);
  1. strcat - 连接字符串
strcat(str1, str2);

注意:
(1)str1必须足够大,以便容纳连接后的新字符串
(2)连接前两字符串后面都有\0
  1. strcpy 和 strncpy - 字符串复制
strcpy(str1,str2);  //  将str2复制到str1

strcpy(str1,str2,n);    //将str2最前面n个字符复制到str1中
  1. strcmp
strcmp(str1,str2);

(1)如全部字符相同,则认为两个字符串相等
(2)若出现不相同字符,则以第一队不相同的字符的比较结果为准

函数值:
(1)相等,则返回0
(2)str1 > str2,返回正整数
(3)str1 < str2,返回负整数
  1. strlen
strlen(str);    //字符长度,不包含\0
  1. strlwr - 小写,strupr - 大写

7.4 习题(第六章)

#include <stdio.h>
#include <math.h>
int main()
{int i,j,n,a[101];
  for (i=1;i<=100;i++)
      a[i]=i;
  a[1]=0;
  for (i=2;i<sqrt(100);i++)
    for (j=i+1;j<=100;j++)
       {if(a[i]!=0 && a[j]!=0)
	      if (a[j]%a[i]==0)
	        a[j]=0; 
       }
  printf("\n");
  for (i=2,n=0;i<=100;i++)
    { if(a[i]!=0)
	    {printf("%5d",a[i]);
         n++;
        }
      if(n==10)
        {printf("\n");
         n=0;
        }
    }
  printf("\n");
  return 0;
}

#include <stdio.h>
int main()
{ int a[11]={1,4,6,9,13,16,19,28,40,100};
  int temp1,temp2,number,end,i,j;
  printf("array a:\n");
  for (i=0;i<10;i++)
    printf("%5d",a[i]);
  printf("\n");
  printf("insert data:");
  scanf("%d",&number);
  end=a[9];
  if (number>end)
    a[10]=number;
  else
   {for (i=0;i<10;i++)
    {if (a[i]>number)
       {temp1=a[i];
	a[i]=number;
	for (j=i+1;j<11;j++)
	  {temp2=a[j];
	   a[j]=temp1;
	   temp1=temp2;
	  }
	  break;
       }
    }
  }
  printf("Now array a:\n");
  for (i=0;i<11;i++)
    printf("%5d",a[i]);
  printf("\n");
  return 0;
 }

//一个数组中元素逆序
//以中间元素为中心,两侧元素互换即可
#include <stdio.h>
#define N 5
int main()
{ int a[N],i,temp;
  printf("enter array a:\n"); 
  for (i=0;i<N;i++)
    scanf("%d",&a[i]);
  printf("array a:\n");
  for (i=0;i<N;i++)
    printf("%4d",a[i]);
  for (i=0;i<N/2;i++)            //循环的作用是将对称的元素的值互换
    { temp=a[i];
      a[i]=a[N-i-1];
      a[N-i-1]=temp;
     }
  printf("\nNow,array a:\n");
  for (i=0;i<N;i++)
    printf("%4d",a[i]);
  printf("\n");
  return 0;
 }   

重点:杨辉三角

#include <stdio.h>
# define N 10
int main(){
  int i,j,a[N][N];
  for(i=0;i<N;i++){
  	a[i][i]=1;
  	a[i][0]=1;
  }
  for(i=2;i<N;i++){
  	for(j=1;j<=i-1;j++){
  		a[i][j]=a[i-1][j]+a[i-1][j-1];
	  }
  }
  for(i=0;i<N;i++){
  	for(j=0;j<=i;j++)
  		printf("%6d", a[i][j]);
  	printf("\n");
  }
  return 0;
 }

//图形输出
#include <stdio.h>
int main()
{ char a[5]={'*','*','*','*','*'};
  int i,j,k;
  char space=' ';
  for (i=0;i<5;i++)
   { printf("\n");
     printf("    ");
     for (j=1;j<=i;j++)
       printf("%c",space);
     for (k=0;k<5;k++)
       printf("%c",a[k]);
   }
  printf("\n");
  return 0;
}

//非凯撒密码,对称密码
#include <stdio.h>
int main()
 {int j,n;
  char ch[80];
  printf("input cipher code:\n");
  gets(ch);
  printf("\ncipher code:%s\n",ch);
  j=0;
  while (ch[j]!='\0')
  { if ((ch[j]>='A') && (ch[j]<='Z'))
      ch[j]=155-ch[j];
    else if ((ch[j]>='a') && (ch[j]<='z'))
      ch[j]=219-ch[j];
    else
      ch[j]=ch[j];
    j++;
  }
  n=j;
  printf("original text:");
  for (j=0;j<n;j++)
    putchar(ch[j]);
  printf("\n");
  return 0;
 }

//strcat实现    不用strlen的方法
//s1[i++]=s2[j++]
#include <stdio.h>
int main()
{ char s1[80],s2[40];
  int i=0,j=0;
  printf("input string1:");
  scanf("%s",s1);
  printf("input string2:");
  scanf("%s",s2);
  while (s1[i]!='\0')
    i++;
  while(s2[j]!='\0')
    s1[i++]=s2[j++];
  s1[i]='\0';
  printf("\nThe new string is:%s\n",s1);
  return 0;
 }

//strcmp实现
#include <stdio.h>
int main()
{ int i,resu;
  char s1[100],s2[100];
  printf("input string1:");
  gets(s1);
  printf("\ninput string2:");
  gets(s2);
  i=0;
  while ((s1[i]==s2[i]) && (s1[i]!='\0'))i++;
  if (s1[i]=='\0' && s2[i]=='\0')
	  resu=0;
  else
      resu=s1[i]-s2[i];
  printf("\nresult:%d.\n",resu);
  return 0;
 }

//strcpy实现 运用了strlen
#include <stdio.h>
#include <string.h>
int main()
{ char s1[80],s2[80];
  int i;
  printf("input s2:");
  scanf("%s",s2);
  for (i=0;i<=strlen(s2);i++)
     s1[i]=s2[i];
  printf("s1:%s\n",s1);
  return 0;
 }

8 函数

8.1 定义函数

定义函数别忘了声明函数

8.2 数组作为函数参数

数组名作为函数参数时,传递的是数组首元素的地址,也就是说形参的值改变,实参的值也改变

float score[10];
average(score);

float average(float array[10]){
    ……
}

8.3 局部变量和全局变量

8.3.1 局部变量
(1)在一个函数内部定义即为局部变量
(2)形式参数也是局部变量
8.3.2 全局变量

在函数外部定义

为区别全局变量和局部变量,习惯将全局变量的第一个字母用大写表示

8.4 变量的存储方式和生存期

8.4.1 动态存储方式和静态存储方式

静态存储方式是指在程序运行期间由系统分配的固定的存储空间,动态存储方式是在程序运行期间根据需要进行动态分配

C 的存储类别包括四种:自动(auto),静态(static),寄存器(register),外部(extern)

8.4.2 局部变量存储类别
  1. 自动变量(auto 变量)
    默认为自动变量,在调用该函数时,系统会给这些变量分配存储空间,在函数调用结束时就自动释放这些存储空间。
  2. 静态局部变量(static 局部变量)
    局部变量的值在调用结束后不消失,下一次再调用该函数时,使用该值。

注意

虽静态局部变量在函数结束调用后仍存在,但其他函数不能调用它。
  1. 寄存器变量(register)
8.3.3 全局变量存储方式

全局变量都存储在静态存储区中

拓展外部变量的作用域:

  1. 在一个文件内拓展
//将 A,B,C 使用范围拓展到定义之前
int main(){
    extern int A,B,C;
    ……
}

int A,B,C
  1. 拓展到其他文件
file1:
int A;
int main(){
    ……
}

file2:
extern A;
……
  1. 将外部变量作用域限制在本文件中
/// 添加static声明
file1:
static int A;
int main(){
    ……
}

file2:
extern A;
……

8.5 内部函数和外部函数

8.6 习题(第七章)

//函数递归应用
#include <stdio.h>
double P(int n,int x);
int main(){
	int n,x;
	double result;
	printf("n,x:");
	scanf("%d,%d",&n,&x);
	result=P(n,x);
	printf("%f",result);
}
double P(int n,int x){
	if(n==0){
		return 1;
	}
	else if(n==1){
		return x;
	}
	else if(n>=1){
		return (2*n-1)*x-P(n-1,x)-(n-1)*P(n-2,x)/n;
	}
}
![](https://image-1251466963.cos.ap-chengdu.myqcloud.com/qiniu/20200301143808.png)
#include <stdio.h>
int main()
{ void convert(int n);
  int number;
  printf("input an integer: ");
  scanf("%d",&number);
  printf("output: ");
  if (number<0)
    {putchar('-');putchar(' ');   /* 先输出一个‘-’号和空格 */
     number=-number;
    }
  convert(number);
  printf("\n");
  return 0;
}
 
void convert(int n)
{ int i;
  if ((i=n/10)!=0)
    convert(i);
  putchar(n%10+'0');
  putchar(32);
}

9 指针

9.1 指针变量

  1. 定义
int *point_1, *point_2;
  1. 引用指针变量
p=&a;
*p=1;


(1)& 取地址符
(2)* 指针运算符(或间接访问运算符),*p代表指针变量p指向的对象
  1. 指针变量作函数参数
    实现了调用函数使变量的值发生变化,在main函数中就可以使用这些改变了的值

9.2 指针引用数组

  1. 数组元素的指针
int *p;
int a[10]={0,1,2,3,4,5,6,7,8,9};

p=a;    //将a数组首元素的指针赋给p
或
p=&a[0];
  1. 数组元素指针的计算
p++;    //指向下一个元素地址
p--;    //指向前一个元素地址
  1. 指向多维数组

9.3 指针引用字符串

char *string="I love China";

9.4 内存动态分配

#include <stdlib.h>
  1. malloc
或 #include <malloc.h>
malloc(100);    //开辟100字节临时分配空间
  1. calloc
p=calloc(50,4);     //分配50个4字节空间
  1. free
free(p);    //释放空间
  1. realloc
relloc(p,50);   //改变分配空间的大小

10 结构体

10.1 定义和使用

定义

struct Student{
  int num;
  char sex;
} student1,student2;    //  注意分号

or

struct Student student1,student2;

初始化和使用

student1={11011,'M'};

student.num=10010;  //使用 . 引用结构体内变量

10.2 结构体指针

struct Student stu_1;
struct Student *p;
p=&stu_1;

引用结构体中变量三种方法:

(1)stu.num
(2)(*p).num
(3)p->num   //替代了第二种写法, '->' 称为指向运算符

10.3 共用体类型

共享一段内存的结构,后一个数据会覆盖前面的数据

union Data{
    int i;
    char ch;
    float f;
}

10.4 枚举类型

一个变量只有几种可能的值

enum Weekday{sun,mon,tue,wed,thu,fri,sat};

10.5 typedef声明新类型名

一般用法:
typedef int Integer;

结构体;
typedef struct{
    int mouth;
    int day;
    int year;
}Date;

11 文件输入输出

文件类型指针 stdio.h

11.1 打开与关闭文件

fopen打开文件

#include <stdio.h>
FILE *fp;
fp=fopen("al","r"); //注意双引号

文件使用方式

fclose关闭文件

fclose(fp);

11.2 顺序读写文件

11.2.1 读写字符
fgetc(fp);
fputc(ch,fp);

或

getc(fp);   //stdio.h 中宏定义,和fgetc相同
putc(ch,fp);
11.2.2 读写字符串
fgets(str,n,fp);
fputs(str,fp);
11.2.3 格式化读写文件
fscanf(fp,"%d %f",&i,&f);
fprintf(fp,"%d,%6.2f",i,f);
11.2.4 二进制方式读写数据

fread(&stud[i],sizeof(struct Student_type),1,fp);
fwrite(&stud[i],sizeof(struct Student_type),1,fp);

11.3 文件位置标记与随机读写

  1. rewind 使文件位置标记指向文件开头
rewind(fp1);
  1. fseek改变文件位置标记
  2. ftell测定当前文件标记位置

11.4 文件读写的出错检测

12 位运算

12.1 按位与(&)

代码

#include "stdio.h"
int main()
{
	int a,b;
	a=077;
	b=a&3;
	printf("\40: The a & b(decimal) is %d \n",b);
	b&=7;
	printf("\40: The a & b(decimal) is %d \n",b);
}

样例输出

 : The a & b(decimal) is 3
 : The a & b(decimal) is 3

12.2 按位或(|)

代码

#include "stdio.h"
main()
{
	int a,b;
	a=077;
	printf("%d",a);
	b=a|3;
	printf("\40: The a & b(decimal) is %d \n",b);
	b|=7;
	printf("\40: The a & b(decimal) is %d \n",b);
}

样例输出

63 : The a & b(decimal) is 63
 : The a & b(decimal) is 63

12.3 异或(^)

同 0 异 1

代码

#include "stdio.h"
main()
{
	int a,b;
	a=7;
	b=3;
	printf("%d",a^b);
	return 0; 
}

样例输出

4

12.4 取反(~)

代码

#include "stdio.h"
main()
{
	int a,b;
	a=7;
	printf("%x",~a);
	return 0; 
}

样例输出

fffffff8

12.5 移位运算

代码

#include "stdio.h"
main()
{
	int a,b;
	a=7;
	printf("%x",a>>2);
	return 0; 
}

样例输出

1

常用C库函数

1. 数学函数

#include <math.h> 或 #include "math.h"
函数名功能函数原型
abs绝对值int abs(intx);
fabs绝对值double fabs(double x);
expe^xdouble exp(double x);
floor不大于x的最大整数double floor(double x);
loglnxdouble log(double x);
log10lgxdouble log10(double x);
powx^ydouoble pow(double x, double y);
sqrt√xdouble sqrt(double x);

计算log2n,使用换底公式

image-20200316134153930
log(n)/log(2);

2. 字符函数

#include <ctype.h>
函数名功能函数原型
isanum判断是否数字int isanum(int ch);
islower判断是否小写字母int islower(int ch);
isupper判断是否大写字母int isupper(int ch);

3. 字符串函数

#include <string.h>

# include <string.h>
void *memset(void *s, int c, unsigned long n);

4. 输入输出函数

#include <stdio.h>

5. 存储动态分配函数

运算符优先级

image-20200401135701567

同一优先级的运算符,结合次序由结合方向所决定。

简单记就是:! > 算术运算符 > 关系运算符 > && > || > 赋值运算符

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值