现在开始,从0开始学C语言!

282 阅读8分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

C语言基础

4、控制语句

在这里插入图片描述

4.1 if

if-else语句 if语句概述 if (表达式) 语句块1 else 语句块2 常见形式: 1.简化形式 if(表达式) 语句块
例如: if(x>y)printf(“%d”, x); 2.阶梯形式 if(表达式1) 语句块1 else if(表达式2) 语句块2 else if(表达式3) 语句块3 else if(表达式4) 语句块4 ... else 语句块n

注意:
语句块:当有若干条语句时,必须用{…}括起来。
表达式: 
一般情况下为逻辑表达式或关系表达式
如:if(a= =b && x= =y)  printf(“a=b,x=y”);
也可以是任意类型(包括整型、实型、字符型、指针类型)
如:if(‘a’) printf(“%d”,’a’);
请区分if(x=1)与if(x= =1)的不同。

3.嵌套形式 if() if() 语句块1 else 语句块2 else if() 语句块3 else 语句块4

if语句的嵌套
else总是与它上面的最近的if配对,与书写格式无关。
要实行强行的配对关系可以利用{ }		
如:if()
	{if()	语句块1}
	 else 语句块2
例:
#include <stdio.h>
int main()
{
float a = 4,b = 5,c = 2,t;
if(a>b) {t=a;a=b;b=t;}
if(a>c) {t=a;a=c;c=t;}
if(b>c) {t=b;b=c;c=t;}
printf(“%5.2f,%5.2f,%5.2f”,a,b,c);
return 0;
}

4.2 switch

switch语句的基本形式

switch case分支结构
	switch(变量/表达式){
		case 1:
			执行语句;
			breakcase 2:
			执行语句;
			breakcase n:
			执行语句;
			breakdefault:
			执行语句;
			//break;可以省略不写
	}

switch语句的使用: ==每个常量表达式的值必须各不相同,否则将会出现矛盾==。 当表达式的值与case后面的常量表达式值相等时,就执行此case后面的语句。 ==switch中的表达式可以是整型、字符型表达式或枚举==。 case 常量:只起语句标号的作用。 switch语句的使用: break语句用于强行跳出switch体,一般每个case后面应有一个break语句,==default分支后的break可以省略==。 ==多个case可以执行一组语句==。 每个case执行完后需要执行break退出分支结构,否则会从当前执行的分支一直向下执行到break或整个分支的结尾才能结束;

4.3 while/goto

循环结构程序 goto语句构成循环 while构成循环 do-while循环 for循环 1.goto语句

goto语句构成循环
int fun(inta)
{   intresult = 0;	
    char*buffer = kmalloc(SIZE);
   if(buffer == NULL)
          return-ENOMEM;
        if(condition1) {	
          while(loop1) {
           ... 
        } 	
  result = 1; 
       goto out;	
  } 	
out: 	
	    kfree(buffer); 
	    return result;
} 	

while 当条件表达式成立的时候,执行循环体,直到表达式不成立,结束循环体的执行,开始执行后面内容

基本形式
while (表达式) {
	循环体;
}
	int i = 1;
	while(i<5){
		printf("%d\n",i);
		i++;
	}
大括号里面的内容是循环重复执行的代码
循环变量初始化:一般放在循环体外部进行初始化
循环退出条件:条件判断的表达式
循环变量的修改:无限趋近于退出条件
while(1);//死循环

do-while

基本形式
do {
	循环体;
}while(表达式);
注意分号不能省略
执行逻辑:先执行一次循环体,然后进入条件表达式,判断是否成立,如果成立继续执行循环体,不成立退出循环
循环变量初始化:do语句前
循环退出条件:while后的条件表达式中
循环变量修改:放在循环体中
do{
	}while(1); while(!0);
//死循环

4.4 for

一般形式 for(expression1; expression2; expression3) { statements;} 执行过程 1.先求解表达式1; 2.求解表达式2,若为真,则执行循环体,然后执行步骤3;若为假,则执行步骤5; 3.求解表达式3; 4.转回执行步骤2; 5.执行for下面的语句。

for语句构成循环	 	
例如:
for(i=1;i<=100;i++)
{
   sum=sum+i;
}
for语句构成循环
表达式1可省略,但循环之前应给循环变量赋值;
表达式2可省略,将陷入死循环
表达式3可省略,但在循环体中增加使循环变量值改变的语句
for(;;){
	循环体
}//死循环

4.5 循环辅助语句

break 用于从循环体内跳出循环体,即提前结束循环。 break只能用在循环语句和switch语句中。 for(r=1;r<=10;r++){ area=pirr; if(area>100) break; printf(“%f”,area); } gcc -std=c99 filename

5、数组和字符串

1.构造数据类型之一 2.数组是具有一定顺序关系的若干个变量的集合,组成数组的各个变量称为数组的元素 3.数组中各元素的数据类型要求相同,用数组名和下标确定。数组可以是一维的,也可以是多维的

5.1一维数组

所谓一维数组是指只有一个下标的数组。它在计算机的内存中是连续存储的。 C语言中,一维数组的说明一般形式如下: <存储类型> <数据类型 > <数组名>[<表达式>] 在这里插入图片描述

对地址的访问用%p	
#include <stdio.h>
int main(int argc, char *argv[])
{
        //int i = 6, a[i];
        int a[6] = {1, 4, 5}, i, n;
        int b[] = {3, 4, 7, 8, 1, 0};
        //求b数组中的元素个数
        n = sizeof(b) / sizeof(int);
        for (i = 0; i < n; i++)
        //printf("%p", &a[i]);
         printf("%p\n", &b[i]);
        //a = a + 1; 错误
        //地址常量不能进行加减
        printf("%p\n", a); 
        printf("%d\n", sizeof(a));
        --->24
        return 0;
}

==注意事项== C语言对数组不作越界检查,使用时要注意 int a[5]; a[5] = 10 × 越界了 关于用变量定义数组维数 int i = 15; int a[i]

5.1.1 一维数组的引用

1.数组必须先定义,后使用 2.只能逐个引用数组元素,不能一次引用整个3.数组 4.数组元素表示形式:数组名[下标] 其中:下标可以是常量或整型表达式

   int a[10]; 
   printf(“%d”, a); (×)   
   for(j=0;j<10;j++)
       printf(“%d\t”, a[j]); (√)  

5.1.2 一维数组的初始化

1.初始化方式:在定义数组时,为数组元素赋初值 int a[5]={1,2,3,4,5}; 2.说明 A.数组不初始化,其元素值为随机数 B.对static数组元素不赋初值,系统会自动赋以0值

static int a[5];
等价于:a[0]=0;  a[1]=0; a[2]=0; a[3]=0; a[4]=0;

C.只给部分数组元素赋初值

int a[5]={6,2,3};
等价于:a[0]=6; a[1]=2;a[2]=3; a[3]=0; a[4]=0;
int a[3]={6,2,3,5,1};     (×)
//全部初始化
int a[]={1,2,3,4,5,6};//编译系统根据初值个数确定数组维数

5.2 二维数组

二维数组的定义 定义方式:==(声明时列数不能省略,行数可以)== 数据类型 数组名[常量表达式][常量表达式]; 元素个数=行数*列数

int a[3][4];  
     float b[2][5];
     int c[2][3][4];

数组元素的存放顺序 原因:内存是一维的 二维数组:按行序优先 在这里插入图片描述 a[0],a[1],a[2]为一维数组名又叫行名 ==一维数组名不可以进行改变,是一个地址常量,为该行元素的首地址,且sizeof(a[0])为a[0]这一行元素占用的内存的空间== a+3是可以的,但是a=a+3 错误 在这里插入图片描述

5.2.1 二维数组元素的引用

形式:数组名[下标][下标] 二维数组元素的初始化 第一种:分行初始化 第二种:按元素排列顺序初始化

//全部初始化
int a[2][3]={{1,2,3},{4,5,6}};
//部分初始化
int a[2][3]={{1,2},{4}};--->1,2,0
							4,0,0
int a[2][3]={{1,2}};--->1,2,0
						0,0,0
//行数省略部分初始化
int a[][3]={{1},{4,5}};--->1,0,0
						   4,5,0
int a[3][3]={{1},{4,5}};--->1,0,0
						   	4,5,0
						   	0,0,0
int a[3][3]={1,2,3,4};报警--->1,2,3
							 4,0,0
							 0,0,0	
int a[3][]={{1},{2,3},{4}}; 错误							 					   	

5.2.2 多维数组

在这里插入图片描述 打印杨辉三角的前十行 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1 ....

#include <stdio.h>
 
int main(int argc, char *argv[])
{
        int a[10][10] = {{0}};
        int i, j;
        for (i = 0; i < 10; i++) {
                a[i][0] = 1;
                for (j = 1; j <= i; j++)
                        a[i][j] = a[i-1][j-1] + a[i-1][j];
        }
        for (i = 0; i < 10; i++)  {
                for (j = 0; j <= i; j++)
                		//往右边补8个空格
                        printf("%-8d ", a[i][j]);
                putchar('\n');
        }
        return 0;
}

有一个2×3的矩阵,要求输出其中值最大的元素的值,以及它的行号和列号。

#include <stdio.h>
int main(int argc, char *argv[])
{
        int a[2][3] = {{2, 5, 8}, {21, 56, 9}};
        int i, j, row, column;
        row = column = 0;
        for (i = 0; i < 2; i++)  {
                for (j = 0; j < 3; j++) {
                        if (a[row][column] < a[i][j]) {
                                row = i;
                                column = j;
                        }
                }
        }
        for (i = 0; i < 2; i++)  {
                for (j = 0; j < 3; j++)
                        printf("%5d ", a[i][j]);
                putchar('\n');
        }
        printf("max=%d %d %d\n", a[row][column], row, column);
        return 0;
}

5.3字符数组和字符串

5.3.1 字符数组

字符数组是元素的数据类型为字符类型的数组 char c[10], ch[3][4]; 字符数组的初始化 1.逐个字符赋值

//以下数组叫字符数组
		char ch[5]={'H','e','l','l','o'};
		//以下数组叫字符数组又叫字符串
		char ch[5]={'B','o','y'};
		--->B o y \0 \0

2.用字符串常量

char ch[6]={“Hello”};
           char ch[6]=“Hello”;
           char ch[]=“Hello”;
#include <stdio.h>
int main(int argc, char *argv[])
{
        char arr1[] = {'a', 'b', 'c'};
        char arr2[6] = {'d', 'e', 'f'};
        printf("arr1:%s %p\n", arr1, &arr1[2]);
        printf("arr2:%s %p\n", arr2, arr2);      
        return 0;
}
---->输出结果为:abcdef
				def 

在这里插入图片描述

#include <stdio.h>
int main(int argc, char *argv[])
{
        char fruit[][20] = {"banana", "apple", "strawmerry", "watermelen"};
        int i, j, n, m;
        //计算二维数组的行和列
        n = sizeof(fruit) / sizeof(fruit[0]);
        m = sizeof(fruit[0]) / sizeof(char);
        for (i = 0; i < n; i++) {
               printf("%s\n",fruit[i]);
               // for (j = 0; j < m; j++)
               //        putchar(fruit[i][j]);
               //putchar('\n');
        }
        return 0;
}

5.3.2 字符串

C语言中无字符串变量,用字符数组处理字符串 字符串结束标志:‘\0’

例  “hello”共5个字符,在内存占6个字节,字符串长度5

输入一个字符串,然后将其逆序输出 解法一:

#include <stdio.h>
#include <string.h>
#define N 20
int main(int argc, char *argv[])
{
        char arr[N] = {0};
        int i, n;
        printf("Please input a string:");
        gets(arr);
        n = strlen(arr);
        for (i = n-1; i >= 0; i--)
                putchar(arr[i]);
        putchar('\n');
        return 0;
}

解法二:

#include <stdio.h>
#include <string.h>
#define N 20
int main(int argc, char *argv[])
{
        char arr[N] = {0};
        int i, j, n, ch;
        printf("Please input a string:");
        gets(arr);
        n = strlen(arr);
        i = 0;
        j = n-1;
        while (i < j) {
                ch = arr[i];
                arr[i] = arr[j];
                arr[j] = ch;
                i++;
                j--;
        }
        puts(arr);
        return 0;
}

C库中实现了很多字符串处理函数 #include <string.h> 几个常见的字符串处理函数 求字符串长度的函数strlen 字符串拷贝函数strcpy 字符串连接函数strcat 字符串比较函数strcmp

5.3.3 strlen

strlen算的是有效长度,不含\0;sizeof是计算占用的总的空间(含有\0) 字符串长度函数strlen 格式:strlen(字符数组) 功能:计算字符串长度 返值:==返回字符串实际长度,不包括‘\0’在内== \xhh表示十六进制数代表的符号 \ddd表示8进制的

例:对于以下字符串,strlen(s)的值为:
char  s[10]={‘A’,'0',‘B’,‘C’,‘\0’,‘D’};
char  s[10]={‘A’,‘\0’,‘B’,‘C’,‘\0’,‘D’};
char  s[ ]=“\t\v\\\0will\n”;
char  s[ ]=“\x69\141\n”; 
char  s[ ]=“\tab\ncnvd\\e”; 
答案:4   1   3   3   9
5.3.4 strcpy

字符串拷贝函数strcpy 格式:strcpy(字符数组1,字符串2) 功能:将字符串2,拷贝到字符数组1中去 返值:返回字符数组1的首地址 说明: 1.字符数组1必须足够大 2.拷贝时‘\0’一同拷贝

#include <stdio.h>
#include <string.h>
#define N 30
int main(int argc, char *argv[])
{
        char src[] = "makeru";
        char dest[N];
        int i, n;
        //strcpy(dest, src);
        i = 0;
        n = strlen(src);
        printf("n=%d\n", n);
        while ( i <= n) {
                dest[i] = src[i];
                i++;
        }
        puts(src);
        puts(dest);
        return 0;
}
5.3.5 strcat

字符串连接函数strcat 格式:strcat(字符数组1,字符数组2) 功能:把字符数组2连到字符数组1后面 返值:返回字符数组1的首地址 说明: 1.字符数组1必须足够大 2.连接前,两串均以‘\0’结束;连接后,串1的 ‘\0’取消,新串最后加‘\0’

#include <string.h>
#include <stdio.h>
int main()
{  
 char destination[25];
 char blank[] = " ", c[]= "C++",turbo[] = "Turbo";
 strcpy(destination, turbo);
 strcat(destination, blank);
 strcat(destination, c);
 printf("%s\n", destination);
 return 0;
}
----->Turbo C++
#include <stdio.h>
#include <string.h>
#define N 100
int main(int argc, char *argv[])
{
        char dest[] = {'a', 'b', 'c'};
        char src[N] = ".com.cn";
        strcat(dest, src);
        printf("dest:%p src:%p\n", dest, src);
        puts(src);
        puts(dest);
        return 0;
}
----->.com.cn
	  abc.com.cn.com.cn
5.3.6 strcmp

字符串比较函数strcmp 格 式:strcmp(字符串1,字符串2) 功 能:比较两个字符串 比较规则:对两串从左向右逐个字符比较
(ASCII码),直到遇到不同字符或‘\0’为止
返 值:返回int型整数 a. 若字符串1< 字符串2, 返回负整数 b. 若字符串1> 字符串2, 返回正整数 c. 若字符串1== 字符串2, 返回零

5.3.7其他字符串函数

strncpy(p, p1, n) 复制指定长度字符串

#include <stdio.h>
#include <string.h>
#define N 30
int main(int argc, char *argv[])
{
        char src[] = "makeru";
        char dest[N] = ".com.cn";
        strncpy(dest, src, 4);
        puts(src);
        puts(dest);
        return 0;
}
---->makeru
	 make.cn

strncat(p, p1, n) 附加指定长度字符串

#include <stdio.h>
#include <string.h>
#define N 30
int main(int argc, char *argv[])
{
        char src[] = "makeru";
        char dest[N] = ".com.cn";
        strncat(dest, src, 4);
        puts(src);
        puts(dest);
        return 0;
}
---->makeru
	 .com.cnmake

strcasecmp忽略大小写比较字符串 strncmp(p, p1, n) 比较指定长度字符串

#include <stdio.h>
#include <string.h>
#define N 30
int main(int argc, char *argv[])
{
        char s1[] = "QUIT";
        char s2[] = "quit";
        printf("%d\n", strncmp(s1, s2, 4));
        printf("%d\n", strcasecmp(s1, s2));
        return 0;
}

strchr(p, c) 在字符串中查找指定字符 //p为字符串,c为要查找的字符,返回值为第一次出现的c在字符串中的位置 strrchr(p,c)返回最后一次出现的c的位置

#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
        char s1[] = "abas$f$sf";
        int ch;
        ch = '$';
        //printf("%p %p \n", s1, strchr(s1, ch));
        //printf("%p %p \n", s1, strrchr(s1, ch));
        printf("%d\n", strchr(s1, ch)-s1);
        printf("%d \n", strrchr(s1, ch)-s1);
        return 0;
}

strstr(p, p1) 查找字符串

#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
        char s[] = "how are you";
        char subs[] = "are";
        printf("%d\n", strstr(s, subs)-s);
        return 0;
}
---->4

isalpha() 检查是否为字母字符 isupper() 检查是否为大写字母字符 islower() 检查是否为小写字母字符 isdigit() 检查是否为数字

#include <stdio.h>
#include <ctype.h>
int main(int argc, char *argv[])
{
        int ch;
        while ((ch = getchar()) != EOF) {
                if (isalpha(ch)) {
                        if (isupper(ch))
 							printf("Upper:%c\n", ch);
                        if (islower(ch))
           					printf("Lower:%c\n", ch);
                }
                if (isdigit(ch))
                        printf("Digit:%d %c\n", ch-'0', ch);
                putchar(ch);
        }
        return 0;
}

tolower() 转换为小写字母字符 ,返回值为转换后的小写字母 toupper() 转换为大写字母字符,返回值为转换后的大写字母

#include <stdio.h>
#include <ctype.h>
int main(int argc, char *argv[])
{
        int ch;
        while ((ch = getchar()) != EOF) {
                if (isalpha(ch)) {
                        if (isupper(ch)) {
                                ch = tolower(ch);
                        }
                        else {
                                ch = toupper(ch);
                        }
                        printf("%c\n", ch);
                }
        }
        return 0;
}