C语言 | 第十三章 | 二维数组 冒泡排序 字符串指针 断点调试

P 120 数组应用案例 2023/1/29

一、应用案例

案例一:创建一个char类型的26个元素的数组,分别 放置’A’-'Z‘。使用for循环访问所有元素并打印出来。提示:字符数据运算 ‘A’+1 -> ‘B’

#include<stdio.h>void main(){/*创建一个char类型的26个元素的数组,分别 放置'A'-'Z‘。使用for循环访问所有元素并打印出来。提示:字符数据运算 'A'+1 -> 'B*/char arr[26];int i;for(i = 0; i < 26 ; i++){arr[i] = 'A' + i; // 第一个是0,A+0依然是0}for(i = 0; i < 26; i++){printf("arr[%d]=%c\n",arr,arr[i]);}getchar();
}

案例二:请求出一个数组的最大值,并得到对应的下标。

#include<stdio.h>
void main(){/*请求出一个数组的最大值,并得到对应的下标。分析:1.自定义数组大小52.假定第一个元素max= arr[0]就是最大值,然后我们依次和数组后面的数进行比较,如果发现有比max更大的数,就相应的变化,遍历完整个数组,max就是最大数。*/int arr[] = {0,-1,89,99,4};int arrLen = sizeof(arr) / sizeof(int);int max = arr[0];int maxIndex = 0;int i;for(i = 1; i < arrLen; i++){    // 这里 i 的初始值为1;因为为0则是和自己比较没有意义// 发现有比max更大的数,就相应的变化if(arr[i] > max){max  = arr[i];maxIndex = i; // 对应下标就是i,所以把i 赋值即可}}printf("max = %d maxIndex = %d",max,maxIndex); // 99,3getchar();
}

P 121 字符串介绍和内存布局 2023/1/29

一、字符数组的介绍

基本介绍:用来存放字符数组称为字符数组, 看几个案例。

char a[10]; //一维字符数组, 长度为10
char b[5][10]; //二维字符数组, 后面我们详细介绍二维数组
char c[20]={'c', ' ', 'p', 'r', 'o', 'g', 'r', 'a','m'}; // 给部分数组元素赋值

总结:字符数组实际上是一系列字符的集合,也就是字符串(String)。在C语言中,没有专门的字符串变量,没有string类型,通常就用一个字符数组来存放一个字符串。

#include<stdio.h>
void main(){// c是一个一维字符数组,给部分元素赋值char c[20]={'t','o','m'};// 输出printf("%s",c);	  // 输出tomgetchar();
}

二、字符串注意事项

  1. 在 C 语言中,字符串实际上是使用 null 字符 (‘\0’) [null字符就是\0,因为ASCII 0 表示空],终止的一维字符数组。因此,一个以 null 结尾的字符串,包含了组成字符串的字符。【以下为内存布局图】
  2. '\0’是ASCII码表中的第0个字符,用NUL表示,称为空字符。该字符既不能显示,也不是控制字符,输出该字符不会有任何效果,它在C语言中仅作为字符串的结束标志。
  3. 字符数组(字符串)在内存中的布局分析 [案例]。

image-20230129180936276

  1. 思考 char str[3] = {‘a’,‘b’,‘c’} 输出什么? 为什么?
	char c[7]={'t','o','m'}; 
// 正常输出tomchar str[3] = {'a','b','c'};
// 输出a,b,c后,后面可能会出现乱码,一些垃圾值char str[] = {'a','b','c'};
// 不指定长度,输出结果可能同样会出现乱码

分析示意图:

image-20230129182746533

结论:如果在给某个字符数组赋值时,(1)赋给的元素的个数小于该数组的长度,则会自动在后面加 ‘\0’, 表示字符串结束,(2)赋给的元素的个数等于该数组的长度,则不会自动添加 ‘\0’。

P 122 字符指针和内存布局 2023/1/30

一、字符串的访问和遍历

小结:因为字符串的本质就是字符数组,因此可以按照数组的方式遍历和访问某个元素即可, 案例如下:

#include<stdio.h>
#include<string.h>
void main(){// 这种方式定义字符数组不会出现任何的乱码,会自动添加一个\0char greeting[] = "Hello";  int i;int len  = strlen(greeting);  // len = 5printf("\n greeting = %s",greeting);printf("\nlen=%d", len);printf("\n字符串第3个字符是=%c", greeting[2]); // 下标是从0开始的,第三个字符for(i = 0; i < len; i++) {printf("\n%c", greeting[i]);}getchar();
}
  • 内存布局

image-20230130115430132

二、字符串的表示形式

  • 用字符数组存放一个字符串

1 . char str[]=“hello tom”;

2 . char str2[] = {‘h’, ‘e’};

  • 用字符指针指向一个字符串

1 . 比如: char pStr=" hello";*

#include<stdio.h>
void main(){// 使用一个指针pStr,指向一个字符数组char* pStr = "Hello";printf("\n pStr指向的字符串= %s",pStr); // 输出Hellogetchar();
}

2 . 总结:

  • C语言对字符串常量" hello"是按字符数组处理的,在内存中开辟了一个字符数组用来存放字符串常量,程序在定义字符串指针变量str时只是把字符串首地址(即存放字符串的字符数组的首地址)赋给pStr。
  • 内存布局图

image-20230130120200916

  • printf(“%s\n”,str); 可以输出 str 指向的字符串。

三、两种方法表示字符串的讨论

  1. 字符数组由若干个元素组成,每个元素放一个字符;而字符指针变量中存放的是地址(字符串/字符数组的首地址),绝不是将字符串放到字符指针变量中(是字符串首地址)。

  2. 对字符数组只能对各个元素赋值,不能用以下方法对字符数组赋值:

char str[14];   // str 实际是一个常量str=" hello tom"; //错误str[0] = 'i'; //ok ,因为只是找到第一个元素在那里填了一个i而已

内存布局图:

image-20230130131706012

  1. 对字符指针变量,采用下面方法赋值, 是可以的:
#include<stdio.h>
void main(){char* a="yes";// 赋值前的地址:printf("\na本身的地址是%p,指向的地址是%p",&a,a);a=" hello tom";   // 定义一个字符指针变量时,可以多次赋值// 赋值后的地址:printf("\na本身的地址是%p,指向的地址是%p",&a,a);printf("\n%s",a);getchar();
}

image-20230130133405513

内存布局图:

image-20230130132914387

  1. 如果定义了一个字符数组,那么它有确定的内存地址(即字符数组名是一个常量);而定义一个字符指针变量时,它并未指向某个确定的字符数据,并且可以多次赋值 [代码+图解]。

P 123 字符数组注意事项和细节 2023/1/31

一、字符串相关函数回顾

  • 常用字符串函数一览
序号函数目的
1strcpy(s1, s2);复制字符串 s2 到字符串 s1。
2strcat(s1, s2);连接字符串 s2 到字符串 s1 的末尾。
3strlen(s1);返回字符串 s1 的长度。
4strcmp(s1, s2);如果 s1 和 s2 是相同的,则返回 0;如果 s1<s2 则返回小于 0;如果 s1>s2 则返回大于 0。
5strchr(s1, ch);返回一个指针,指向字符串 s1 中字符 ch 的第一次出现的位置。
6strstr(s1, s2);返回一个指针,指向字符串 s1 中字符串 s2 的第一次出现的位置。
#include<stdio.h>
#include<string.h>void main(){char str1[12] = "Hello";char str2[12] = "World";char str3[12];int len ; /* 复制 str1 到 str3 */strcpy(str3, str1);   // str3内容 "Hello"printf("strcpy( str3, str1) : %s\n", str3 );/* 连接 str1 和 str2 */strcat( str1, str2);printf("strcat( str1, str2): %s\n", str1 );  // "Hello world"/* 连接后,str1 的总长度 */len = strlen(str1);   // 因为进行了连接,所以总长度应该是10,10个字符printf("strlen(str1) : %d\n", len );if(strcmp(str1, str2)<0){printf("小于0");}else{printf("大于0");}getchar();
}

二、字符数组使用注意事项和细节

  1. 程序中往往依靠检测 ‘\0’ 的位置来判定字符串是否结束,而不是根据数组的长度来决定字符串长度。因此,字符串长度不会统计 ‘\0’, 字符数组长度会统计 [案例]。

  2. 在定义字符数组时应估计实际字符串长度,保证数组长度始终大于字符串实际长度,否则,在输出字符数组时可能出现未知字符。

  3. 系统对字符串常量也自动加一个’\0’作为结束符。例如"C Program”共有9个字符,但在内存中占10个字节,最后一个字节’\0’是系统自动加上的。(通过sizeof()函数可验证)。

  4. 定义字符数组时,如果 给的字符个数 比 数组的长度小,则系统会默认将剩余的元素空间,全部设置为 ‘\0’, 比如 char str[6] = “ab” , str内存布局就是[a] [b] [ \0 ] [\0] [\0] [\0]。

  5. 字符数组定义和初始化的方式比较多,比如:

#include<stdio.h>void main(){char str1[ ]={"I am happy"}; // 默认后面加 '\0'char str2[ ]="I am happy"; // 省略{}号 ,默认后面加 '\0'char str3[ ]={'I',' ','a','m',' ','h','a','p','p','y'}; // 字符数组后面不会加 '\0', 可能有乱码char str4[5]={'C','h','i','n','a'}; //字符数组后面不会加 '\0', 可能有乱码char * pStr = "hello";		 // OK, 使用一个指针pStr,指向一个字符数组printf("\n str1 = %s",str1);printf("\n str1 = %s",str2);printf("\n str1 = %s",str3);printf("\n str1 = %s",str4);getchar();
}

P 124 冒泡排序分析和实现 2023/1/31

一、排序算法

介绍:排序也称排序算法(Sort Algorithm),排序是将一组数据,依指定的顺序进行排列的过程。

排序的分类:

  1. 内部排序:指将需要处理的所有数据都加载到**内部存储器(内存)**中进行排序。

  2. 外部排序法:数据量过大,无法全部加载到内存中,需要借助外部存储进行排序。

二、冒泡排序

基本介绍:冒泡排序(Bubble Sorting)的基本思想是:通过对待排序序列从前向后(从下标较小的元素开始),依次比较相邻元素的值,若发现逆序则交换,使值较大的元素逐渐从前移向后部,就象水底下的气泡一样逐渐向上冒。

结论:因为排序的过程中,各元素不断接近自己的位置,如果一趟比较下来没有进行过交换,就说明序列有序,因此要在排序过程中设置一个标志flag判断元素是否进行过交换。从而减少不必要的比较。

  • 冒泡排序应用实例

案例:我们举一个具体的案例来说明冒泡法。我们将五个无序的数:{3, 9, -1, 10, -2}使用冒泡排序法将其排成一个从小到大的有序数列。

分析过程:

// 	冒泡排序的过程(从小到大) ===> 分析过程(思路) ===》 代码原始数组{3, 9, -1, 10, -2}1轮排序:
(1)  3,9-1,10-2
(2) 3,-1,9,10,-2
(3) 3,-1,9,10,-2
(4)3,-1,9,-2,10  // 第1大的数就移动到最后2轮排序:
(1) -1,3,9,-2,10
(2)-1,3,9,-2,10
(3)-1,3,-2,9,10 //第2大的数就移动适当位置3轮排序:
(1)-1,3,-2,9,10
(2)-1,-2,3,9,10 第3大的数就移动适当位置4轮排序:
(1) -2,-1,3,9,10//第4大的数就移动适当位置
排序结束
// 是不需要进行第五轮的比较,因为四个数都已经找到合适的位置了

将上述的分析过程然后写成代码:

#include<stdio.h>void main(){int arr[] = {3,9,-1,10,-2};// 因为每次排序几乎一样,因此,我们可以使用for循环处理int j;int t;  // 临时变量// 第一轮排序:for(j = 0; j < 4; j++){// 如果前面的数大于后面的数就,交换if(arr[j] > arr[j+1]){t = arr[j];arr[j] = arr[j+1];arr[j+1] = t;}}// 输出看看第一轮排序的的情况 for(j = 0 ; j < 5 ; j++){printf("%d ",arr[j]);}printf("\n");// 第二轮排序:for(j = 0; j < 3; j++){  // 第二轮比较3次就可以了,因为前一轮最大数已经固定了// 如果前面的数大于后面的数就,交换if(arr[j] > arr[j+1]){t = arr[j];arr[j] = arr[j+1];arr[j+1] = t;}}for(j = 0 ; j < 5 ; j++){printf("%d ",arr[j]);}printf("\n");// 第三轮排序:for(j = 0; j < 2; j++){  // 第二轮比较2次就可以了,因为前两轮已经固定两个数// 如果前面的数大于后面的数就,交换if(arr[j] > arr[j+1]){t = arr[j];arr[j] = arr[j+1];arr[j+1] = t;}}for(j = 0 ; j < 5 ; j++){printf("%d ",arr[j]);}printf("\n");// 第四轮排序:for(j = 0; j < 1; j++){  // 第二轮比较2次就可以了// 如果前面的数大于后面的数就,交换if(arr[j] > arr[j+1]){t = arr[j];arr[j] = arr[j+1];arr[j+1] = t;}}for(j = 0 ; j < 5 ; j++){printf("%d ",arr[j]);}printf("\n");getchar();
} 

代码优化:

// 因为每次排序几乎一样,因此,我们可以使用for循环处理
#include<stdio.h>void main(){int arr[] = {3,9,-1,10,-2,-11,989};// 因为每次排序几乎一样,因此,我们可以使用for循环处理int j;int i;int t;  // 临时变量int arrLen = sizeof(arr) / sizeof(int);  // 数组的大小,通过计算得到,这样就很方便,可以随意改变数组大小for(i = 0 ; i < arrLen-1 ; i++){  // 这里可以写活,刚好等于数组的大小减1// 第一层循环就是总的轮数for(j = 0; j < arrLen-1-i; j++){// 第二层循环就是执行交换,进行轮中的排序// 如果前面的数大于后面的数就,交换if(arr[j] > arr[j+1]){   // 从大到小,把大于改成小于就可以了t = arr[j];arr[j] = arr[j+1];arr[j+1] = t;}}// 获取每一轮循环后的结果for(j = 0 ; j < arrLen ; j++){printf("%d ",arr[j]);}printf("\n"); // 每一轮循环输出结果后换行}getchar();
}

函数优化处理:

#include<stdio.h>// 冒泡排序的函数:
void bubbleSort(int arr[],int arrLen){// 因为每次排序几乎一样,因此,我们可以使用for循环处理int j;int i;int t;  // 临时变量for(i = 0 ; i < arrLen-1 ; i++){  // 这里可以写活,刚好等于数组的大小减1// 第一层循环就是总的轮数for(j = 0; j < arrLen-1-i; j++){// 第二层循环就是执行交换,进行轮中的排序// 如果前面的数大于后面的数就,交换if(arr[j] > arr[j+1]){   // 从大到小,把大于改成小于就可以了t = arr[j];arr[j] = arr[j+1];arr[j+1] = t;}}// 获取每一轮循环后的结果for(j = 0 ; j < arrLen ; j++){printf("%d ",arr[j]);}printf("\n"); // 每一轮循环输出结果后换行}
}void main(){int j;int arr[] = {3,9,-1,10,-2,-11,};int arrLen = sizeof(arr) / sizeof(int);  // 数组的大小,通过计算得到,这样就很方便,可以随意改变数组大小bubbleSort(arr,arrLen);  // 数组默认是地址传递(指针)getchar();
}

总结: 以上案例的优化过程总结了前面所学,进行了一个综合。

P 125 顺序查找和二分查找 2023/2/1

一、基本介绍

在C中,我们常用的查找有两种

1) 顺序查找

2) 二分查找(默写)【比较重要】

  • 案例演示:

二、顺序查找

案例一:有一个数列:{23, 1, 34,89, 101},猜数游戏:从键盘中任意输入一个数,判断数列中是否包含该数,

【顺序查找】要求: 如果找到了,就提示找到,并给出下标值, 找不到提示 没有。

#include<stdio.h>int seqSearch(int arr[], int arrLen, int val){int i;for(i = 0; i < arrLen ; i++){if(val == arr[i]){return i;}}// 如果在for循环中,没有执行到return,说明没有找到return -1; // 可以返回一个-1,因为下标是没有-1的
}void main(){/*有一个数列:{23, 1, 34,89, 101},猜数游戏:从键盘中任意输入一个数,判断数列中是否包含该数,【顺序查找】要求: 如果找到了,就提示找到,并给出下标值, 找不到提示 没有。*/// 分析思路://1. 按照数组进行数组进行遍历,如果相等则找到。int arr[] = {23,1,34,89,101};int arrLen = sizeof(arr) / sizeof(int);int index = seqSearch(arr,arrLen,-101); // 将形参传入进去,返回值用index进行接收if(index != -1){printf("找到了下标为%d",index);}else{printf("没有找到");}getchar();
}

三、二分查找

案例二:请对一个有序数组进行【二分查找】 {1,8, 10, 89, 1000, 1234} ,输入一个数看看该数组是否存在此数,并且求出下标,如果没有就提示"没有这个数"
二分查找的前提是,该数组是一个有序数组。

#include<stdio.h>// 二分查找:
int binarySearch(int arr[], int leftIndex, int rightIndex, int findVal){// 先找到中间这个数midValint midIndex = (leftIndex + rightIndex) / 2;  // 比如数组大小为5,左下标(0+5)/2=2.5取整为2int midVal = arr[midIndex];   // 中间值//如果leftIndexf > rightIndex ,说明这个数组都比较过,但是没有找到。// 因为:leftIndex是在逐渐向右边移动,rightIndex是逐渐向左边移动,所以如果左边大于右边,// 就说明已经将整个数组范围全部查找完但是没有找到。if(leftIndex > rightIndex){return -1;  // !!!}// 如果midVal > finVal说明 应该在midVal的左边去查找if(midVal > findVal){binarySearch(arr,leftIndex,midIndex-1,findVal); // !!! 函数递归,递归相当于缩小范围进行查找// 如果midVal < finaVal说明 应该在midVal的右边去查找}else if(midVal < findVal){binarySearch(arr,midIndex+1,rightIndex,findVal); // 在右边查找,右边索引不变,左边索引加一}else{return midIndex;  // 返回该数的下标}}
void main(){/*请对一个有序数组进行二分查找 {1,8, 10, 89, 1000, 1234} ,输入一个数看看该数组是否存在此数,并且求出下标,如果没有就提示"没有这个数"。二分查找的前提是,该数组是一个有序数组*/int arr[]= {1,8, 10, 89, 1000, 1234};int arrLen = sizeof(arr) / sizeof(int);int index = binarySearch(arr, 0 ,arrLen-1,-1234);  // 这里长度-1,因为下标从0开始,得到长度是6,但第六个下标为5if(index != -1){printf("index = %d",index);}else{printf("没有找到");}getchar();// 思路分析:// 比如我们要查找的数是findVal// 1.先找到 数组中间这个数midVal,和finVal比较// 2.如果midVal > finVal说明 应该在midVal的左边去查找// 3.如果midVal < finVal说明 应该在midVal的右边去查找// 4. 如果midVal == findVal ,说明找到// 5. 如果leftIndexf > rightIndex ,说明这个数组都比较过,但是没有找到
}

P 126 二维数组的基本使用 2023/2/1

一、基本介绍

多维数组我们介绍二维数组。

  • 应用场景

比如我们开发一个五子棋游戏,棋盘就是需要二维数组来表示。如图:

image-20230201161024628

二、入门案例

**案例一:**请用二维数组输出如下图形。

image-20230201162349511

#include<stdio.h>
void main () {// a[4][6]  :表示的是一个4行6列的二维数组// (1)先定义在初始化:int a[4][6]; // 没有初始化,则是分配的内存垃圾值(不确定的值)int i, j;//全部初始化 0for(i = 0; i < 4; i++) {      // 先遍历行for(j = 0; j < 6; j++) {  //  在遍历列a[i][j] = 0;}}a[1][2] = 1;a[2][1] = 2;a[2][3] = 3;// 输出二维数组for(i = 0; i < 4; i++) {for(j = 0; j < 6; j++) {//printf("a[%d][%d]=%d ", i, j, a[i][j]);printf("%d ", a[i][j]);}printf("\n");}

相关地址输出:

	//看看二维数组的内存布局printf("\n二维数组a的首地址=%p", a);printf("\n二维数组a[0]的地址=%p", a[0]);printf("\n二维数组a[0][0]的地址=%p", &a[0][0]);printf("\n二维数组a[0][1]的地址=%p", &a[0][1]);//将二维数组的各个元素得地址输出printf("\n");for(i = 0; i < 4; i++) {printf("a[%d]的地址=%p ", i, a[i]);   // 输出a[0-4]的地址for(j=0; j < 6; j++) {printf("a[%d][%d]的地址=%p ", i, j , &a[i][j]); // 输出全部地址}
// 地址是连续分部的,虽然看着换行了,第二行的第一个元素地址是上一行最后加4printf("\n");	}getchar();
}

内存分析图:

image-20230201170914734

总结:

  1. 语法: 类型 数组名[大小] [大小],比如: int a [2] [3];
  1. 二维数组在内存的存在形式,各个元素的地址是连续分布的,即在前一个元素基础上+4(int类型)。

三、直接初始化

  • 定义 类型 数组名[大小] [大小] = {{值1,值2…},{值1,值2…},{值1,值2…}};
    或者 类型 数组名[大小] [大小] = { 值1,值2,值3,值4,值5,值6 …};

image-20230201171744020

P 127 二维数组的应用案例 2023/2/2

一、应用案例

案例一:请使用灵活的方式遍历如下数组 :

int map[3][3] = {{0,0,1},{1,1,1},{1,1,3}};

#include<stdio.h>void main(){int  map[3][3] = {{0,0,1},{1,1,1},{1,1,3}};// 遍历// 先得到行// 1. sizeof(map) 得到这个map数组的大小 9 * 4 = 36// 2. sizeof(map[0]) 得到map中,第一行有多大 3 * 4 = 12int rows = sizeof(map) / sizeof(map[0]);  // 3个元素//printf("rows = %d",rows);// 得到列int cols = sizeof(map[0]) / sizeof(int);  // 一行的大小是12,int占4字节,除以4可以得到列。 sizeof([0][0])int i;int j;for(i = 0; i < rows; i++){for(j = 0; j < cols; j++){printf("%d ",map[i][j]);}printf("\n");}getchar();
}

案例二:int arr[3][2]={{4,6},{1,4},{-2,8}};遍历该二维数组,并得到和?

#include<stdio.h>void main(){int arr[3][2]={{4,6},{1,4},{-2,8}};int i,j;int sum = 0;int rows = sizeof(arr) / sizeof(arr[0]);int column = sizeof(arr[0]) / sizeof(int);for(i = 0; i < rows ; i++){for(j = 0; j < column ; j++){printf("%d ",arr[i][j]);sum += arr[i][j];  // 定义一个sum,每次累加}printf("\n");}printf("sum=%d",sum);  // 21 getchar();
}

案例三:定义二维数组,用于保存三个班,每个班五名同学成绩,并求出每个班级平均分、以及所有班级平均分【 数据要求从控制台输入 】

#include<stdio.h>void main(){/*定义二维数组,用于保存三个班,每个班五名同学成绩,并求出每个班级平均分、以及所有班级平均分【 数据要求从控制台输入 】*/// 分析:// 1 .创建一个scores[3][5]// 2. 遍历,给赋值// 3. 再次遍历统计总分和平均分// 4. 最后输出double score[3][5]; //int rows = sizeof(score) / sizeof(score[0]),cols = sizeof(score[0]) / sizeof(double), i, j; // //classTotalScore 各个班级总成绩, totalScore 所有学生成绩double totalScore = 0.0, classTotalScore = 0.0;  // 定义所有班级总成绩、个各班的成绩for (i = 0; i < rows; i++ ) {for (j = 0; j < cols ; j++ ) {score[i][j] = 0.0;  // 初始化}}//遍历给每个学生输入成绩for (i = 0; i < rows; i++ ) {for (j = 0; j < cols ; j++ ) {printf("请输入第 %d 个班的 第 %d 个 学生的成绩", i + 1, j + 1); // 下标从0开始,但是没有第0个班,所以+1scanf("%lf", &score[i][j]);}}// 显示成绩情况for(i = 0; i < rows ; i++){for(j = 0 ; j < cols; j++){printf("%.2f  ",score[i][j]);}printf("\n");}// 统计各个班的总成绩,和所有学生的总成绩for(i = 0; i < rows; i++){classTotalScore = 0.0; // 每次清0,这样才能统计每个班的总分for(j = 0; j < cols; j++){classTotalScore += score[i][j];}printf("\n 第%d个班的平均成绩时%.2f",i+1,classTotalScore/cols);totalScore += classTotalScore;   //  将该班级的总分,累积到totalScore}printf("\n 所有学生的总成绩是 %.2f ,平均成绩%.2f",totalScore,totalScore/(rows * cols)); // 平均成绩=总成绩/人数(rows * cols)getchar();getchar();
} 

image-20230202124408624

P 128 二维数组的注意事项和细节 2023/2/2

一、注意事项

  1. 可以只对部分元素赋值,未赋值的元素自动取“零”值【案例】。
#include<stdio.h>int main(){int a[4][5] = {{1},{2},{3},{1}};  // 每行后面是没有赋值的//{1}等价于 {1,0,0,0,0} int i,j;for(i = 0; i < 4; i++){for(j = 0; j < 5; j++){printf("%d ",a[i][j]);}printf("\n");}getchar();
}

image-20230202170107381

  1. 如果对全部元素赋值,那么第一维的长度可以不给出(二维数组可以省略行)。比如:
int a[3][3] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; 
可以写为: 
int a[][3] = {1, 2, 3, 4, 5, 6, 7, 8, 9};  // 是等价于前面的写法
  1. 二维数组可以看作是由一维数组嵌套而成的;如果一个数组的每个元素又是一个数组,那么它就是二维数组。
// 二维数组a[3][4]可看成三个一维数组,它们的数组名分别为 a[0]、a[1]、a[2]。
// 这三个一维数组都有 4 个元素,如,一维数组 a[0] 的元素为 a[0][0]、a[0][1]、a[0][2]、a[0][3]

image-20230202171022644

P 129 断点调试介绍和快捷键 2023/2/3

一、需求引入

引入:在开发中,程序员发现一个非常诡异的错误,怎么看源代码都发现不了这个错误,这时老程序员就会温馨提示,可以使用断点调试,一步一步的看源码执行的过程,从而发现错误所在。

基本介绍:断点调试是指自己在程序的某一行设置一个断点,调试时,程序运行到这一行就会停住,然后你可以一步一步往下调试,调试过程中可以看各个变量当前的值,出错的话,调试到出错的代码行即显示错误,停下。然后程序可以进行分析从而找到这个Bug。

二、断点调试的快捷键

F5开始调试、执行到下一个断点
F11逐句执行代码,会进入到函数体
F10逐过程执行(遇到函数,不会进入到函数体)
Shift+F11跳出(跳出某个函数,跳出前会将该函数执行完)
Shiit+F5终止调试

P 130 断点调试应用案例(1)2023/2/3

一、应用案例

案例一:看一下变量的变化情况等:(逐过程执行代码……)

#include<stdio.h>
void main() {int sum = 0;int i = 0;for(i = 0; i < 10; i++) {sum += i;printf("\n i=%d", i);printf("\n sum=%d", sum);}printf("退出for循环了~~");
}

image-20230203125254302

image-20230203125503125

image-20230203125659108

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1559234.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Mysql中创建用户并设置任何主机连接

Mysql中创建用户并设置任何主机连接 文章目录 Mysql中创建用户并设置任何主机连接背景解决方式 背景 在linux上安装mysql,默认用户是root,但是用navicat连接不了,必须要用ssh隧道连接,现在想用任何主机只要输入账号密码之后就可以连接 解决方式 #创建一个指定用户和IP链接的用…

通过祖先序列重建辅助工程化UDP-糖基转移酶-文献精读64

Engineering the Substrate Specificity of UDP-Glycosyltransferases for Synthesizing Triterpenoid Glycosides with a Linear Trisaccharide as Aided by Ancestral Sequence Reconstruction 通过祖先序列重建辅助工程化UDP-糖基转移酶的底物特异性&#xff0c;用于合成具…

股市有人吹的“哨音”也应倾听

国庆节前&#xff0c;深圳东方港湾投资管理股份有限公司董事长但斌发微博警告说&#xff1a;“这样暴涨&#xff0c;必有暴跌&#xff0c;这次如果再被套住&#xff0c;该动员的力量都动员了解套将遥遥无期”他这样警告&#xff0c;就与新冠病毒刚在武汉爆发时的“吹哨人”起的…

重头开始嵌入式第四十六天(硬件 ARM裸机开发 ADC 中断 UART)

目录 ADC使用 1.什么是ADC&#xff1f; 一、功能 二、工作原理 三、参数指标 四、应用领域 2.如何配置s3c2440中的adc&#xff1f; 中断 1.什么是中断&#xff1f; 一、定义 二、中断的作用 三、中断的类型 四、中断处理过程 2.如何配置中断&#xff1f; UART 1…

一站式服务,产业园运营让创业更轻松!

一站式服务&#xff0c;也被称为“一条龙服务”或“全流程服务”&#xff0c;它是指企业或机构为了满足客户或用户的需求&#xff0c;整合内部资源&#xff0c;通过优化服务流程、提高服务效率&#xff0c;从而提供从咨询、受理、办理到反馈等各个环节的完整、连续、高效的服务…

汽车主机厂主数据管理中一物多码或多码一物问题的具体表现有哪些?

数据入口多导致重复编码 在汽车主机厂的主数据管理中&#xff0c;由于存在多个数据入口&#xff0c;不同部门或环节可能会独立进行数据录入。这就容易出现一物多码或多码一物的情况。例如&#xff0c;采购部门、生产部门、物流部门等可能各自采用不同的编码体系来标识同一种汽…

车辆路径规划问题(VRP)优化方案

车辆路径规划问题&#xff08;VRP&#xff09;优化方案 车辆路径规划问题&#xff08;Vehicle Routing Problem, VRP&#xff09;是物流领域中一个经典的组合优化问题&#xff0c;目标是在满足客户需求的情况下&#xff0c;找到一组车辆的最优配送路径&#xff0c;以最小化总的…

PMP11月考试中文报名10月9日开始!

经过PMI与中国国际人才交流基金会的联合研究决定&#xff0c;2024年度第四期PMI认证考试将于11月30日进行。 为了让各位考生能够充分准备&#xff0c;我们特此梳理了本次考试的具体安排及注意事项&#xff0c;请务必仔细阅读&#xff01; 报名时间安排&#xff1a; &#xf…

使用Python批量修改文件修改日期为随机的6到8月份

使用Python批量修改文件修改日期为随机的6到8月份 每当雪花飘起的时候&#xff0c;总有一股抹不去的情节&#xff0c;会想起儿时雪天的记忆&#xff0c;虽然模糊但也清晰。那时每年的冬季很冷&#xff0c;但依然喜欢飘雪的日子&#xff0c;看着满天迷蒙飘舞的雪花总有想不完的心…

microsoft edge浏览器卡死问题

win11经常遇到microsoft edge浏览器卡死的情况&#xff0c;有时候是一会没用浏览器就全部卡死&#xff0c;有时候是锁屏或者电脑休眠浏览器就不能用&#xff0c;找了很多的办法都没好使&#xff0c;用以下方法好使了&#xff1a; edge浏览器中打开 edge://settings/system 把 …

架设传奇SF时提示此服务器满员,GEE引擎点开始游戏弹出服务器满员的解决方法

昨天一个朋友在架设GEE的传奇服务端时遇到一个奇怪的问题&#xff0c;就是在服务器外网架设时&#xff0c;建好角色点开始游戏提示此服务器满员&#xff0c;这个问题一般比较少见&#xff0c;而且出现的话一般都是GEE引擎的版本。 他折腾了半天&#xff0c;一直没进游戏&#x…

apt update报错:ModuleNotFoundError: No module named ‘apt_pkg‘(可能是默认python版本被改坏了)

文章目录 错误信息分析1. 确保 apt_pkg 模块已安装2. 检查 Python 版本3. 重新配置 Python4. 修复损坏的依赖5. 检查环境变量 尝试 错误信息 (base) rootkyai:/ky/tml/ky_ai_get_server_info# apt update 获取:1 file:/var/cuda-repo-cross-aarch64-ubuntu2004-11-4-local InR…

简易入门:使用Docke 部署一个tomcat服务

简易入门&#xff1a;使用Docke 部署一个tomcat服务 # 拉取 >docker pull tomcat:9.0# 后台运行容器&#xff0c;端口映射为8080. -p 宿主机端口:容器端口 >docker run -d --name tomcat-c-01 -p 8080:8080 tomcat:9.0# 查看容器id >docker ps CONTAINER ID IMAG…

Go语言对接微信支付与退款全流程指南

在互联网技术日益发展的今天&#xff0c;线上支付已成为不可或缺的一部分。作为一门简洁高效的编程语言&#xff0c;Go&#xff08;又称Golang&#xff09;凭借其强大的并发处理能力和高效性能&#xff0c;在后端开发领域越来越受到开发者的青睐。本文将详细介绍如何使用Go语言…

【Java SE基础回顾】看这篇就够了!

JavaSE复习 参考视频&#xff1a;【狂神说Java】JavaSE阶段回顾总结 简单的就不讲了&#xff0c;比如什么break和continue区别&#xff0c;甚至一些什么什么继承封装多态的概念等等。 主要写一些Java特有的&#xff0c;重点的基础知识。主要还是例子和代码更多&#xff0c;更有…

对象存储之阿里云OSS最详细的实现

Hello&#xff0c;大家好&#xff0c;我是Feri&#xff0c;一枚十多年的程序员&#xff0c;同时也是一名在读研究生&#xff0c;关注我&#xff0c;且看一个平凡的程序员如何在自我成长&#xff0c;只为各位小伙伴提供编程相关干货知识&#xff0c;希望在自我蜕变的路上&#x…

【JS】环形链表怎么找入口?

思路 判断是否有环&#xff1a;定义快慢指针&#xff0c;慢指针&#xff08;slow&#xff09;走一步&#xff0c;快指针&#xff08;fast&#xff09;走两步。 无环&#xff1a;快指针最终会到达链表的末尾&#xff08;即fast.next为null&#xff09;,永远不可能相遇有环&#…

C++ 二叉搜索树转换为双向链表

描述 输入一棵二叉搜索树&#xff0c;将该二叉搜索树转换成一个排序的双向链表: 代码 #include <iostream> #include <string> #include <optional>struct TreeNode {int val;struct TreeNode *left;struct TreeNode *right;TreeNode(int x): val(x), left(…

陈零九全新单曲《也曾想走进你的心底》 揭露爱而不得的情感遗憾

图片提供&#xff1a;种子音乐 “创作男神”陈零九于10月9日推出充满深情的全新创作单曲《也曾想走进你的心底》&#xff0c;这首歌再次延续他招牌的“九式情歌”风格&#xff0c;展现其创作魅力。歌曲以一段“爱而不得”的感情故事为主线&#xff0c;深入探讨人们在爱情中的复…

项目启动 | 盘古信息赋能奥尼视讯数字化转型升级,实现全面数智化发展

随着信息技术的飞速发展与全球市场竞争的日益激烈&#xff0c;传统制造业正面临生存和发展的危机&#xff0c;制造企业为谋求发展&#xff0c;纷纷开启数字化转型之路&#xff0c;深度融入数字技术&#xff0c;实现生产流程的智能化、管理模式的精细化以及产品服务的个性化&…