C语言入门基础学习

  • C语言概述:(7.6)
      • 例1-4 计算两个双精度浮点数的乘法运算
      • 例1-8 动画效果的HelloWorld程序
      • 例1-9 动画效果的HelloWorld程序2
      • 课后练习
  • 数据存储与运算:(7.7)
      • 例2-5 5种有符号整数类型所占字节数及数据范围
      • 例2-7 数据溢出示例
      • 例2-8 浮点类型定义,初始化及输出
      • 例2-12 自增运算符编程实例
      • 例2-16 sizeof运算符获取int空间大小的三种方式
      • 例2-17 显式强制类型转换与自动类型转换示例
      • 例2-18 条件运算符示例
      • 课后练习
  • 简单程序设计:(7.8)
      • 课后练习
  • 循环:(7.11)
      • 课后练习
  • 函数:(7.11)
      • 例5-22 条件编译指令的用法
      • 课后练习
  • 数组:(7.12)
      • 基础知识
      • 例6-2 将一组整数逆置:输入n(n<=10)及n个整数,将这组整数逆置并输出。
      • 例6-3
      • 例6-8 字符串的简单加密
      • 例6-9 系统登陆验证
      • 课后练习
  • 指针:(7.13)
      • 基础知识
      • 例7-3 随机生成指定长度的字符串。
      • 例7-4 与指定数字相同的数的个数
      • 例7-6 通过指针操作数组。
      • 例7-7 在数组中查找元素
      • 例7-8 数组指针访问二维数组
      • 例7-9 指针数组编程示例
      • 例7-10 函数指针示例
      • 例7-11 对用户输入的两个数字,进行加减乘除计算
      • 例7-12 使用qsort()函数完成数组排序
      • 课后练习

C语言概述:(7.6)

每天两小时学习,首先这本书是基于一个控制台文本界面操作函数库mycon,该库是由书籍团队设计完成的。

功能:在字符界面下设置窗体长和宽,设置窗口标题,定位光标,显示光标,隐藏光标,设置字符
的前景色和背景色,延时,清屏,键盘接收,播放声音共10个函数。有了这些能干什么?

作用:借此平台能做到,轻松愉快地开发有声有色地字符界面游戏,动画和实用的小软件(本书已经实现了字符跑马灯,贪吃蛇游戏,空战游戏,赌马游戏,推箱子游戏,读者在此基础上可以设计实现更多的字符界面游戏,如俄罗斯方块,走迷宫,打字练习,各种字符动画广告等。)

C语言程序员主要做的事有两件:写自己的函数使用别人的函数

学会如何熟练地使用标准函数库(这个是跨越Windows和UNIX/Linux等操作系统平台的)

根据开发需要,学会下载安装配置并使用第三方函数库,如图形库,网络库,多线程库等,来提高自己的开发效率,进行各种企业级的实用化开发。

学习程序设计时最有效的方法不是对什么都刨根问底,把遇到的每一点都弄明白,而是应该先不求甚解,努力实践,把它做出来,然后琢磨为什么这么做。

组成C语言程序的若干个函数的代码在整个程序中的位置十分灵活,谁在前,谁在后均可以。

C语言严格区分大小写

程序的本质是模拟客观世界

编写C程序的过程中,推荐大量使用C函数库中的函数来完成需要的功能

例1-4 计算两个双精度浮点数的乘法运算

C语言本身并没有提供输入/输出的语句,它是通过相应的库函数来实现输入/输出的。最常用的输入库函数为scanf,输出库函数为printf 。f 是format的缩写,意思是格式化,对应就是格式化输入和输出。

scanf("格式控制字符串",接收输入的地址列表)printf("格式控制字符串",输出项列表)

例1-4

#include <stdio.h>
int main(void)
{double x1;double x2;printf("请输入第一个数:");scanf("%lf",&x1);  printf("请输入第二个数:");scanf("%lf",&x2);printf("%f * %f = %.2f\n",x1,x2,x1 * x2);return 0;
}

%lf 用于接收 double型
%.2f 用于控制输出项以十进制有符号实数的形式输出,前两位小数,不是保留两位小数。

例1-8 动画效果的HelloWorld程序

#include <stdio.h>
#include <windows.h>
int main(void)
{while(1){printf("H");Sleep(500);printf("e");Sleep(500);printf("l");Sleep(500);printf("l");Sleep(500);printf("o");Sleep(500);printf(",");Sleep(500);printf("W");Sleep(500);printf("o");Sleep(500);printf("r");Sleep(500);printf("l");Sleep(500);printf("d");Sleep(500);printf("!");Sleep(500);printf("\n");}return 0;
} 

有点类似flash动画逐帧出现的感觉,我挺喜欢这类动态的程序。
这一例子添加了 <windows.h> 头文件,调用了其中的库函数Sleep;对应百度百科链接: link.
在Linux下,sleep中的“s”不大写,sleep()单位为秒,usleep()里面的单位是微秒。
上述windows中使用的Sleep(500)时间理论500ms,实际用时超过500ms。

例1-9 动画效果的HelloWorld程序2

\b 退格键,键盘上对应键,叫做Backspace,概念是转义字符,对应百度百科链接链接: link.

输出这两个字符,就会让光标回到本行当前位置的前两个字符位置处,如果此时用printf函数输出一个字符串,那么新的字符串的其实输出位置就是刚才重新定位的光标位置。写出下面程序:

#include <stdio.h>
#include <windows.h>
int main(void)
{while(1){printf("H");//1Sleep(500);printf("e");Sleep(500);printf("l");Sleep(500);printf("l");Sleep(500);printf("o");Sleep(500);printf(",");Sleep(500);printf("W");Sleep(500);printf("o");Sleep(500);printf("r");Sleep(500);printf("l");Sleep(500);printf("d");Sleep(500);printf("!");//12Sleep(500);//下面加入退格键后printf("\b ");	//1 Sleep(500);printf("\b\b ");Sleep(500);printf("\b\b ");Sleep(500);printf("\b\b ");Sleep(500);printf("\b\b ");Sleep(500);printf("\b\b ");Sleep(500);printf("\b\b ");Sleep(500);printf("\b\b ");Sleep(500);printf("\b\b ");Sleep(500);printf("\b\b ");Sleep(500);printf("\b\b ");Sleep(500);printf("\b\b \b");//12Sleep(500);}return 0;
} 

在源代码基础上添加一个while循环,让它一直循环。
//1 只有一个\b和一个空格,缺一不可。这是书上原文,那我不去想为什么,我直接去掉空格看现象。
在这里插入图片描述

去掉空格后从 l 开始了, 原因是格式化打印printf,按“ ”内的顺序执行,
第一个printf执行\b移动到 !后,第二个printf执行\b\b,往后继续移动二到 r 和 l之间,然后输出空格覆盖l,l消失
之所以后续都进行了\b\b两次退格,是因为打印一次空格覆盖内容光标向前移动一格。
基本原理如上,其实是通过 退格 输出空格覆盖 这样的逻辑来完成撤销操作。

课后练习

第一章 第7题 编写程序,让一只小鸟煽动翅膀从左到右飞过(小鸟可以交替用字符C或^表示,即可呈现小鸟煽动翅膀的效果)

首先我们看书籍作者给出的代码。

/*** 飞翔的小鸟 2019年5月5日*/
#include <stdio.h>
#include <windows.h>int main(void)
{printf("飞翔的小鸟:\n");printf("V\r");Sleep(100);printf(" ^\r");Sleep(100);printf("  V\r");Sleep(100);printf("   ^\r");Sleep(100);printf("    V\r");Sleep(100);printf("     ^\r");Sleep(100);printf("      V\r");Sleep(100);printf("       ^\r");Sleep(100);printf("        V\r");Sleep(100);printf("         ^\r");Sleep(100);printf("           V\r");Sleep(100);printf("            ^\r");Sleep(100);printf("             V\r");printf("\n");
}

从我的角度按道理应该是可以对此代码进行升级的,首先抓出一次显示飞翔操作。

	printf("V\r");Sleep(100);printf(" ^\r ");Sleep(100);

然后利用二维坐标轴的思想,让“小鸟”在平面有规律的移动。程序代码如下。

#include <stdio.h>
#include <stdlib.h>
#include <windows.h> 
int main()
{int i,j;int x = 0;int y = 5;int velocity_x = 1;int velocity_y = 1;int left = 0;int right = 20;int top = 0;int bottom = 10;while (1){x = x + velocity_x;y = y + velocity_y;system("cls");   // 清屏函数// 输出小鸟前的空行for(i=0;i<x;i++)printf("\n");for (j=0;j<y;j++)printf(" ");printf("V");//输出小鸟煽动翅膀 Sleep(100);printf("\b^");Sleep(100);printf("\n"); Sleep(50);  // 等待若干毫秒if ((x==top)||(x==bottom))velocity_x = -velocity_x;if ((y==left)||(y==right))velocity_y = -velocity_y;		}return 0;
}

第一章 第8题 A 编写程序,实现两种不同风格的安装进度表示:一种是百分比进度指示(从10%到100%,每次增加10%,如果每次增加1%,则代码太长了);一种是温度计字符进度指示(■■■□□)

/*** 模拟安装进度条*/
#include <stdio.h>
#include <windows.h>int main(void)
{printf("00%%\r");Sleep(100);printf("10%%\r");Sleep(100);printf("20%%\r");Sleep(100);printf("30%%\r");Sleep(100);printf("40%%\r");Sleep(100);printf("50%%\r");Sleep(100);printf("60%%\r");Sleep(100);printf("70%%\r");Sleep(100);printf("80%%\r");Sleep(100);printf("90%%\r");Sleep(100);printf("100%%\r");Sleep(100);printf("\n");return 0;
}

第一章 第8题 B

/*** 模拟安装进度条*/
#include <stdio.h>
#include <windows.h>int main(void)
{printf("模拟安装进度条:\n");printf("□□□□□□□□□□0%%\r");printf("■□□□□□□□□□10%%\r");Sleep(200);printf("■■□□□□□□□□20%%\r");Sleep(200);printf("■■■□□□□□□□30%%\r");Sleep(200);printf("■■■■□□□□□□40%%\r");Sleep(200);printf("■■■■■□□□□□50%%\r");Sleep(200);printf("■■■■■■□□□□60%%\r");Sleep(200);printf("■■■■■■■□□□70%%\r");Sleep(200);printf("■■■■■■■■□□80%%\r");Sleep(200);printf("■■■■■■■■■□90%%\r");Sleep(200);printf("■■■■■■■■■■100%%\r");Sleep(200);printf("\n");return 0;
}

第一章 第9题 编写程序,实现10s倒计时。

/*** 模拟倒计时*/
#include <stdio.h>
#include <windows.h>int main(void)
{printf("10\r");Sleep(1000);printf("9 \r");Sleep(1000);printf("8 \r");Sleep(1000);printf("7 \r");Sleep(1000);printf("6 \r");Sleep(1000);printf("5 \r");Sleep(1000);printf("4 \r");Sleep(1000);printf("3 \r");Sleep(1000);printf("2 \r");Sleep(1000);printf("1 \r");Sleep(1000);printf("0 \r");Sleep(1000);return 0;
}

第一章 第10题 编写一个程序,查看当前计算机是否打开了135端口(请查询netstat命令和find命令的帮助,理解netstat-an|find“135“的含义,并且要特别注意:在字符串,即”和“间的若干字符中如果要使用”字符本身,则必须使用转义字符\“(斜杠加上一个”)来表示一个双引号本身。所谓的端口就是0-65535之间的一个整数,其实代表的是内存中某个网络程序的收发网络数据包的队列,也就是间接地代表了某个网络程序是否打开)。

/*** 编程查看是否打开135端口*/
#include <stdio.h>
#include <stdlib.h>int main(void)
{system("netstat -an | find \"135\"");system("pause>nul");return 0;
}

数据存储与运算:(7.7)

每天两小时学习,从我个人的角度来学习基础知识,就是反复的对自己进行洗脑。

学习目标

  • 理解数据的二进制存储。
  • 掌握C语言的基本数据类型。
  • 掌握变量与常量。
  • 掌握C语言的运算符及表达式。

洗脑内容

  • 计算机能且只能做两种事情:执行计算与保存计算结果。

章节内容

  • 定义变量使用内存,使用运算符进行计算
  • 本章只介绍基本类型,枚举类型和void类型。

基础知识

  • 数据在计算机内存中是以二进制的形式存储的,1个二进制数称为1位,也就是说最小单位:位;也称作 bit 比特
  • 用 位 作单位又嫌弃太小,又采用字节(Byte)作为计算机存储单位,1个字节等于8个比特
  • const定义符号常量,有类型,编译时也可以进行类型检查;对应百度百科链接: link.
  • 一个数据的类型决定了这个数据在内存中所占用空间的大小,以及它的值所采用的编码方式。例如带符号和不带符号的二进制数。
  • 程序中使用的变量名,函数名,标号等统称为标识符。
  • 标识符命名规则:第一个字符必须是字母或下划线,且只能由英文字母,数字,和下划线“_”组成。而且不能是C的关键字和保留标识符。
  • 标识符最好采用英文单词或其组合,切忌使用汉语拼音来命名,且言简意赅
  • C语言严格区分大小写
  • 有符号整型数据在内存中以补码的形式存储。
  • sizeof 运算符可测试数据占几个字节
  • 十进制输出整数 %d,八进制输出 %o,十六进制输出 %x 或 %X,如果要显示进制前缀,类似 %#x,%#X,添加 # 号即可。
  • int类型是最适应计算机系统架构的整数类型。原因:它具有和CPU寄存器相对应的空间大小和位格式。(这句话我在别的书也看过)
  • char 类型实际存储的是整数而不是字符。对应ASCII编码;百度百科链接: link.
  • 对于ascii码,通常记忆是 32 为空格’ ‘; 32 / 2 * 3=48 数字’0’;32 * 2 + 1=65 ‘A’ 32 * 3 + 1 = 97 ‘a’
  • float 精度 6位,表示小数点后6位,而不是保留到小数点后六位
  • 枚举类型可以定义一种新的数据类型,并列举所有的可能值。 百度百科链接: link.
  • 通常不去记运算符优先级,而是利用 () 达到你想要的顺序。 百度百科链接链接: link.
  • 算术运算符中 只有 % 运算符需要整数操作数,其它数据类型不设限。
  • 除法运算,除数为 0 ,程序崩溃,别瞎搞。
  • 逻辑表达式按照从左到右得顺序执行。
  • 显示强制类型转换运算符,目前除了申请空间之外很少用到,不过我还是记录了一道例题。

补充:整数类型可以使用一个或多个类型修饰符进行修饰。

  • signed
  • unsigned
  • short
  • long

补充:转义序列 百度百科链接: link.

例2-5 5种有符号整数类型所占字节数及数据范围

书籍配套源码基础上调整了打印格式后的代码如下:

#include <stdio.h>
#include <limits.h>  //该文件包含了CHAR_MIN、INT_MIN等宏
int main(void)
{   printf("\nsigned char所占字节数:%d,数据范围:[%d,%d]\n\n",sizeof(signed char),SCHAR_MIN,SCHAR_MAX);	printf("short所占字节数:%d,数据范围:[%d,%d]\n\n",sizeof(short),SHRT_MIN,SHRT_MAX); printf("int所占字节数:%d,数据范围:[%d,%d]\n\n",sizeof(int),INT_MIN,INT_MAX);printf("long所占字节数:%d,数据范围:[%ld,%ld]\n\n",sizeof(long),LONG_MIN,LONG_MAX);printf("long long所占字节数:%d,数据范围:[%lld,%lld]\n\n",sizeof(long long),LLONG_MIN,LLONG_MAX);	return 0;
}

输出结果比较正常。
在这里插入图片描述

例2-7 数据溢出示例

溢出行为是未定义的行为,C语言标准并未定义有符号类型的溢出规则。
所以面对这类问题,做到不溢出。

#include <stdio.h> 
#include <limits.h>
int main(void) 
{ int a,b;       // 定义变量a =  INT_MAX ; // 给整型变量a赋一个最大值 (INT_MAX)b = a + 1;     // 最大值加上1后的结果赋给整型变量b	 printf("a = %d\nb = %d\n",a,b); system("pause");return 0; 
}

结果很真实。
在这里插入图片描述

例2-8 浮点类型定义,初始化及输出

我对这个指数表示有点迷茫,感觉这样表示不够 real

#include <stdio.h> 
int main(void) 
{ float x = 320.0f;double y = 2.14e9;long double z = 8.8L;printf("%f也可以写成%e\n",x,x);printf("y的值是 %e\n",y);printf("z的值是 %Lf\n",z);return 0; 
}

以前整天都是%d输出十进制整数,现在我的确应该多看看实数输出的例子。
在这里插入图片描述

例2-12 自增运算符编程实例

#include <stdio.h> 
int main(void) 
{ 	int a,b,c,d;a = 7;b = 7;c = a++;    //后缀形式:先返回a的值,再增1 d = ++b;    //前缀形式:先增1,再返回b值 printf("a=%d,b=%d,c=%d,d=%d\n",a,b,c,d);	return 0; 
}

个人理解:++a(前),运算前先+1;a++(后),先使用最后才+1;
出现这种运算符目的是为了减少运算指令,提高运算效率。
在这里插入图片描述

例2-16 sizeof运算符获取int空间大小的三种方式

个人角度第二种方式比较常用

#include <stdio.h>
int main(void)
{int a;printf("%d\n",sizeof(int));       //第1种方式printf("%d\n",sizeof(a));         //第2种方式printf("%d\n",sizeof a);           //第3种方式return 0;
}

结果很正常。
在这里插入图片描述

例2-17 显式强制类型转换与自动类型转换示例

#include <stdio.h>
int main(void)
{double f = 9.14;      //f是双精度浮点类型变量 int n = (int) f ;         //把f显式强制转换成整数 f = n / 2 ;                            //整除结果是整数4,类型转换自动转换成双精度类型 printf("f = %f n = %d\n",f,n);   f = (double) n / 2 ;               //把n显式强制转换成双精度类型 printf("f = %f n = %d\n",f,n);   return 0;
}

有趣的数据。
在这里插入图片描述

例2-18 条件运算符示例

条件运算符使用率极高,很喜欢用

#include <stdio.h>
int main(void)
{int x = 5,y = 7;int distance = x<y ? y-x : x-y;printf("distance = %d",distance);	return 0;
}

表达式1 ?表达式2 : 表达式3
表达式1 ?(真,就执行) :(假,执行这条)
在这里插入图片描述

课后练习

1.在C语言中为一个特定的数据分配内存时,程序员必须( A )。
A.定义一个数据类型的变量 B.定义一个值
C.声明一个特定数据类型的指针 D.以上都不是

2.若有以下定义:
char w; int x; float y;double z;
则表达式w*x+z-y结果为( D )类型。
A.float B.char C.int D.double

3.下列变量名中,哪些是合法的?哪些是不合法的?为什么?
This_little_pig 2_for_1_special latest things
The_$12_method number correct?
MineMineMine _this_is_ok _foo
答:
合法的变量名有:
This_little_pig number MineMineMine _this_is_ok _foo

4.为下面的变量指定最佳的变量类型。
(1)以米为单位的房间面积。
(2)一小时内通过学校门口的车辆数量。
答:
(1)double 或float
(2)int

5.设x = 3、y=4、z=6,表达式!(x>y)+(y!=z)||(x+y)&&(y-z)的结果是( B )。
A.0 B.1 C.-1 D.6

6.若s是int型变量,且s=6,则s%2+(s+1)%2表达式的值为( 1 )。若a是int型变量,则“(a=45,a2),a+6”表达式的值为( 26 )。若x和a均是int型变量,则执行表达式x = (a=4,6*2)后的x的值为( 12 )。

7.若已知a=10,b=15,c=1,则表达式 a*b&&c 的运算结果是( 1 )。

8.若已定义 int a=25,b=14,c=19,则三元运算符(a>b? c:b)所构成语句的执行结果是( 19 )。

9.设a、b、c为整型数,且a=2、b=3、c=4,则执行语句 a=16+(b++)-(++c);后,a的值是(28)*

10.设 a=5,b=6,c=7,d=8,m=2,n=2,执行(m=a>d) && (n=c>b)后n的值为( 2 )。

11.初始化值是 0.968 的双精度变量 a 的定义形式为( double a = 0.968; )。

12.“200<x≤800”的C语言表达式为( x>200 && x<=800 )。

13.若x为 int 类型变量,则执行以下程序段后的 x 值是( -60 )。
x=6; x+=x-=x*x;

14.设 x 为 int 型变量,判断 x 是偶数的表达式为( x % 2 == 0 )。

15.读程序写运行结果。

#include <stdio.h>int main(void)
{int i = 5,s = 10;s += s-i;printf("i=%d,s=%d\n",i,s);return 0;
}

程序运行结果为:
i=5,s=15

16.读程序写运行结果。

#include <stdio.h>int main(void)
{int a = 4,b = 5,c = 0,d;d = !a&&!b--||!c;printf("b = %d d = %d\n",b,d);return 0;
}

程序运行结果为:
b = 5 d = 1

17.一年大约有3.156×107s。编写一个程序,提示用户输入年龄,然后显示该年龄对应的秒数。
参考代码如下:

#include <stdio.h>
int main(void)
{const double year = 3.156e7; int age;printf("请输入你的年龄:"); scanf("%d",&age);printf("从你出生现现在已经过去了:%.2e秒\n",year*age); return 0;
}

18. 编程实现以下任务:
(1)定义int类型变量x和y,并且x的初始值为10,y的初始值为20。
(2)定义char类型变量ch并初始化为’B’。
(3)将int类型变量x的值加5,从而更新其值。
(4)定义double类型变量z并初始化为50.3。
(5)将int类型变量x和y的值互换。
(6)输出变量x和表达式2*x+5-y的值。

参考代码如下:

#include <stdio.h>
int main(void) 
{int x = 10,y = 20;          //(1)char ch = 'B';              //(2)x += 5;                     //(3)double z = 50.3;            //(4)int t = x;                  //(5)x = y;y = t;printf("x = %d 2*x+5-y = %d\n",x,2*x+5-y);     //(6)return 0;
}

简单程序设计:(7.8)

每天两小时学习,从我个人的角度来学习基础知识,就是反复的对自己进行洗脑。

学习目标

  • 了解算法的概念及算法的描述方法。
  • 掌握几种简单语句的使用
  • 理解分支结构的含义
  • 掌握if语句和switch语句的使用
  • 能够灵活设计顺序结构,分支结构程序。

洗脑内容

  • 沃斯提出:数据结构+算法=程序;实际上,数据结构+算法+程序设计方法+语言工具;
  • 通常判断非0 为真 是0为假

math.h

  • double fabs(double x)求绝对值函数
  • double sqrt(double x)求平方根函数

开关语句

  • switch-case是专用于实现多支结构的选择语句,特点是各分支清晰而且直观。
switch
{case 常量: 语句; break;......case 常量; 语句; break; (default: 语句;)
}
  • case后面的常量表达式的值,必须是整型,字符型或枚举类型。

课后练习

1.C语言中,逻辑“真”等价于( C )。
A.大于零的数 B.大于零的整数 C.非零的数 D.非零的整数

2.对如下程序,若用户输入为A,则输出结果为( B )。

int main(void)
{ char ch;scanf("%c",&ch);ch=(ch>='A'&&ch<='Z')?(ch+32):ch;printf("%c\n",ch);return 0;
}

A.A B.32 C.a D.空格

3.下列表达式中能表示a 在0 到100 之间的是( B )。
A.a>0&a<100 B.!(a<0||a>100)
C.0<a<100 D. !(a>0&&a<100))

4.有如下程序,其输出结果是( C )。

int main(void)
{   int a=2,b=-1,c=2;if(a<b)if(b<0) c=0;else c++;printf("%d\n",c);return 0;
}

A.0 B.1 C.2 D.3

5.有如下程序段:

int main(void)
{int x =1, y=1 ;int m , n;m=n=1;switch (m){   case 0 : x=x*2;case 1: {switch (n){   case 1 : x=x*2;case 2 : y=y*2;break;case 3 : x++;}}case 2 : x++;y++;case 3 : x*=2;y*=2;break;default:x++;y++;}return 0;
}

执行完成后,x 和y 的值分别为( A )。
A.x=6 y=6 B.x=2 y=1 C.x=2 y=2 D.x=7 y=7

6.C语言的switch语句中,case后为( B )。
A.只能为常量
B.只能为常量或常量表达式
C.可为常量及表达式或有确定值的变量及表达式
D.可为任何量或表达式

7.若执行以下程序时从键盘上输入9,则输出结果是( B )。

int main(void)
{   int n;scanf("%d",&n);if(n++<10)   printf("%d\n",n);else         printf("%d\n",n--);return 0;
}

A.11 B.10 C.9 D.8

8.if语句的基本形式是if(表达式)语句,以下关于“表达式”值的叙述中正确的是( D )。
A.必须是逻辑值 B.必须是整数值
C.必须是正数 D.可以是任意合法的数值

9.编程实现少量数排序问题:输入4个任意整数,按从小到大的顺序输出。
参考代码如下:

#include <stdio.h>
int main(void)
{int a,b,c,d;scanf("%d %d %d %d",&a,&b,&c,&d);	if(a>b){int t;t = a;a = b;b = t;}if(b>c){int t;t = b;b = c;c = t;}if(c>d){int t;t = c;c = d;d = t;}if(a>b){int t;t = a;a = b;b = t;}if(b>c){int t;t = b;b = c;c = t;}if(a>b){int t;t = a;a = b;b = t;}printf("%d %d %d %d \n",a,b,c,d);return 0;
}

10.计算邮资:根据邮件的重量和用户是否选择加急计算邮费。计算规则:重量在1000克以内(包括1000克),基本费8元;超过1000克的部分,每500克加收超重费4元,不足500克部分按500克计算;如果用户选择加急,多收5元。
输入一行,包含整数和一个字符,以一个空格分开,分别表示重量(单位为克)和是否加急。如果字符是y,说明选择加急;如果字符是n,说明不加急。
输出一行,包含一个整数,表示邮费。
参考代码如下:

#include <stdio.h>
int main()
{int x,y;char yn;scanf("%d %c",&x,&yn);if(x<=1000) y=8;else {y=8+(x-1000)/500*4;if((x-1000)%500!=0) y+=4;}if(yn=='y') y+=5;printf("%d",y);return 0;
}

11.从键盘接收一个字符,如果是字母,输出其对应的ASCII码;如果是数字,按原样输出,否则给出提示信息:输入错误!。
参考代码如下:

#include <stdio.h>
int main(void)
{char ch;scanf("%c",&ch);if(ch>='a'&&ch<='z' || ch>='A'&&ch<='Z')printf("%d\n",ch);else if(ch>='0'&&ch<='9')printf("%c\n",ch);else printf("输入错误!\n");return 0;
}

12.输入一个字符,判断它是否是小写字母,如果是小写字母,则将它转换成大写字母;如果不是,则不转换,然后输出所得到的字符。
参考代码如下:

#include <stdio.h>
int main(void)
{char ch;scanf("%c",&ch);if(ch>='a'&&ch<='z')ch = ch-'a'+'A'; //ch = ch-32;printf("%c\n",ch);return 0;
}

13.判断输入的正整数是否既是5的倍数又是7的倍数,若是,则输出yes,否则输出no。
参考代码如下:

#include <stdio.h>
int main(void)
{int m;scanf("%d",&m);if(m%5==0 && m%7==0)printf("yes\n");else printf("no\n");	return 0;
}

循环:(7.11)

每天两小时学习,从我个人的角度来学习基础知识,就是反复的对自己进行洗脑。

学习目标

  • 掌握循环结构的本质。
  • 掌握while,do…while及for循环语句的语法格式,执行流程及用法。
  • 掌握循环中断及结束本次循环的方法。
  • 理解循环嵌套结构。
  • 能够灵活设计循环结构程序。

内容

  • goto语句;(汇编学过,没想到C也可以用)百度百科链接 link.
  • 数值计算时,有必要对结果的位数进行推算。变量就不容易出现溢出错误。所以的确有必要对变量的取值范围进行一个记忆,简单记忆那便是要对变量所占内存字节数进行记忆。
  • 枚举法:尝试每一种情况;思想:将问题的所有可能答案一一列举,然后根据条件判断此答案是否符合条件,保留合适的,丢弃不合适的。特点:算法简单,容易理解,但运算量较大。
  • 递推问题:迭代是循环,重复执行一系列运算步骤。

洗脑内容

  • break语句只能用于循环语句和switch语句中。
  • continue语句能够提前终止本次循环,继续下次循环。

课后练习

1.下面的for语句是( C )。
for(x=0,y=10;(y>0)&&(x<4);x++,y-- );
A.无限循环 B.循环次数不定 C.循环执行4次 D.循环执行3次

2.已知int i=1; 执行语句while (i++<4);后,变量i的值为( C )。
A.3 B.4 C.5 D.6

3.求取满足式 12+22+32+ … +n2 ≤1000的n,正确的语句是( A )。
A.for(i=1,s=0;(s=s+ii)<=1000;n=i++);
B.for(i=1,s=0;(s=s+i
i)<=1000;n=++i);
C.for(i=1,s=0;(s=s+i*++i)<=1000;n=i);
D.for(i=1,s=0;(s=s+i*i++)<=1000;n=i);

4.下列循环语句中有语法错误的是( D )。
A.while(x=y) 5; B.while(0) ;
C.do 2; while(xb); D.do x++ while(x10) ;

5.从键盘上输入:ABCdef<回车>,程序的执行结果为( acbDEF )。

#include <stdio.h>
int main (void)
{ char  ch;while ((ch=getchar())!='\n'){if(ch>='A' && ch<='Z')	  ch = ch + 32;else if(ch>='a' && ch<='z')ch = ch-32;printf("%c",ch);}printf("\n");return 0;
}

6.下面程序的执行结果为( )。

#include <stdio.h>
int main(void)
{int  x = 1,y = 0;switch  (x){case 1:switch (y){ 	case 0: printf("**1**\n"); break;case 1: printf("**2**\n"); break;}case 2: printf("**3**\n");} return 0;
}

运行结果为:
1
3
7.写出以下程序输入2,3<回车>时的运行结果,并给出程序的功能。

#include <stdio.h>
int main(void)
{long term=0,sum=0;int a,i,n;printf("Input a,n:");scanf("%d,%d",&a,&n);for(i=1;i<=n;i++){ term=term*10+a;sum += term;}printf("sum=%ld\n",sum);return 0;
}
程序的功能的为:求a+aa+...+a...a(最后一项为n位)的和。

8.最高的分数:孙老师讲授的《计算导论》这门课期中考试刚刚结束,他想知道最高的分数是多少。因为人数比较多,他觉得这件事情交给计算机来做比较方便。你能帮孙老师解决这个问题吗?
输入两行,第一行为整数n(1≤n < 100),表示参加这次考试的人数,第二行是这n个学生的成绩,相邻两个数之间用单个空格隔开。所有成绩均为0到100之间的整数。输出一个整数,即最高的成绩。
参考代码如下:

#include <stdio.h>int main(void)
{int n,x,max;	scanf("%d",&n);max=-1;while(n--){cin>>x;if(x>max) max=x;}	printf("%d\n",max);return 0;
}

9.满足条件的数累加:将正整数 m 和 n 之间(包括 m 和 n)能被 17 整除的数累加。其中,0 < m < n < 1000。
输入一行,包含两个整数m和n,中间以一个空格间隔。输出一行,包含一个整数,表示累加的结果。
参考代码如下:

#include <stdio.h>int main(void)
{int m,n,s;	scanf("%d %d",&m,&n);s=0;int i=m;while(i<=n){if(i%17==0)	s+=i;i++; 	}printf("%d\n",s);return 0;
}

10.满足条件的3位数:编写程序,按从小到大的顺序寻找同时符合条件1和2的所有3位数,条件为:(1)该数为完全平方数;(2)该数至少有两位数字相同。如,100同时满足上面两个条件。
输入一个数n,n的大小不超过实际满足条件的3位数的个数。输出第n个满足条件的3位数(升序)。
参考代码如下:

int a[1000];
int main(void)
{int n,k=0,j=10,i;for(i=j*j;i<1000;j++,i=j*j){if(i%10==i/10%10||i%10==i/100||i/100==i/10%10){a[++k]=i;} 		}scanf("%d",&n);printf("%d\n",a[n]);return 0;
}

11.人口增长问题:我国现有x亿人口,按照每年0.1%的增长速度,n年后将有多少人?
输入一行,包含两个整数x和n,分别是人口基数和年数,以单个空格分隔。输出最后的人口数,以亿为单位,保留到小数点后四位(1≤x≤100, 1≤n≤100)。
参考代码如下:

#include <stdio.h>int main(void)
{int x,n;double s;	scanf("%d %d",&x,&n);s=x;		while(n--){s=s*(1+0.1/100);		}printf("%.4f\n",s);return 0;
}

12.银行利息:农夫约翰在去年赚了一大笔钱!他想要把这些钱用于投资,并对自己能得到多少收益感到好奇。已知投资的复合年利率为R(0到20之间的整数)。约翰现有总值为M的钱(100到1,000,000之间的整数)。他清楚地知道自己要投资Y年(范围0到400)。请帮助他计算最终他会有多少钱,并输出它的整数部分。数据保证输出结果在32位有符号整数范围内。
输入一行包含三个整数R,M,Y,相邻两个整数之间用单个空格隔开。输出一个整数,即约翰最终拥有多少钱(整数部分)。
参考代码如下:

#include <stdio.h>
int main(void)
{int R,M,Y;double s;	scanf("%d %d %d",&R,&M,&Y);s=M;		while(Y--){s=s*(1+1.0*R/100);		}	printf("%d\n",(int)s);return 0;
}

13.买房子:某程序员开始工作,年薪N万,他希望在中关村公馆买一套60平米的房子,现在价格是200万,假设房子价格以每年百分之K增长,并且该程序员未来年薪不变,且不吃不喝,不用缴税,每年所得N万全都积攒起来,问第几年能够买下这套房子(第一年年薪N万,房价200万)?
输入一行,包含两个正整数N(10 ≤ N ≤ 50), K(1≤ K ≤ 20),中间用单个空格隔开。输出如果在第20年或者之前就能买下这套房子,则输出一个整数M,表示最早需要在第M年能买下,否则输出Impossible。
参考代码如下:

#include <stdio.h>
int main(void)
{int N,k;scanf("%d %d",&N,&k);int i=1;double s,hprice=200;while(i<=20&&s<hprice){i++;s=N*i;hprice*=(1+1.0*k/100);}if(i<=20) printf("%d",i);else printf("Impossible");return 0;
}

14.运动场有4位篮球运动员正在进行篮球训练,他们分别来自火箭队,湖人队,森林狼队,凯尔特人队。一位记者问:“你们都来自那个队伍?”
B说:“C球员是凯尔特人队。”
C说:“D球员不是森林狼队。”
A说:“B球员不是火箭队的。”
D说:“他们三个人中,只有凯尔特人队的队员说了实话。”
D的话是可信的,那么他们分别来自那个球队呢?

#include <stdio.h>
void printterm(int n);
int main(void)
{// hj,hr,sl,ke分别用1,2,3,4代表 int A,B,C,D;int la,lb,lc,ld;for(A=1;A<=4;A++){for(B=1;B<=4;B++){	for(C=1;C<=4;C++){for(D=1;D<=4;D++){	if(B!=A&&C!=A&&C!=B&&D!=A && D!=B && D!=C){lb=(C==4);lc=(D!=3);la=(B!=1);if((A==4&&la&&!lb&&!lc) + (B==4&&lb&&!la&&!lc) + C==4&&lc&&!la&&!lb)==1){printf("A来自"); printterm(A);printf("B来自"); printterm(B);printf("C来自"); printterm(C);printf("D来自"); printterm(D);		            	        		   }} 	}}}} 
}
void printterm(int n)
{switch(n){case 1: printf("火箭队\n"); break;case 2: printf("湖人队\n"); break;case 3: printf("森林狼队\n"); break;case 4: printf("凯尔特人队\n"); break;}
}

函数:(7.11)

每天两小时学习,个人的角度学习基础知识,就是反复的对自己进行洗脑。

学习目标

  • 掌握函数的定义,声明,调用及返回
  • 掌握函数形参与实参
  • 掌握函数的嵌套调用与递归调用
  • 理解变量的生存期与作用域
  • 掌握编译预处理及模块化编译链接

内容

  • 递归:程序调用自身的编程技巧;
  • 递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算;百度百科link.
  • 变量的生存期是指变量在什么时间段内存在,变量的作用域是指变量在哪些代码块中能够访问。
  • #ifdef 和 #ifndef;常见的头文件包含如下代码:
#ifndef _XXX_H_
#define _XXX_H_
头文件内容
#endif

含义为:如果已经包含了头文件XXX.h的内容,则不再包含该头文件,否则包含该头文件的内容

  • 特殊符号处理,这里笔者只记录了一个。
    __FILE__:包含当前程序文件名的字符串。 (这个我尝试过,挺有用的)
  • 模块化编译链接;简述就是自己写库函数头文件,再调用。

洗脑内容

  • 对于一个不加return语句的“函数”,编译器会自动加上。

  • 程序中有些变量,在程序加载到内存中时并不分配存储空间,而是到定义它的函数被调用执行时才会临时分配存储空间,并且一旦该函数执行完毕返回到被调用处,这些变量在内存中分配的存储空间也将被回收,即它们将不复存在。这种变量称为非静态局部变量或自动变量,用关键字auto修饰。一个局部变量,如果没有用static修饰,则它自动为auto的。无论是否用auto修饰,自动变量或非静态局部变量的生存期为函数调用时到函数返回时的这个时间段,在此之前和之后它们都不存在。

  • 全局变量,生存期为整个程序的生存期,作用域一般为定义处到它所在的文件结束。

  • 将一些没必要设置成全局变量的变量,实际上浪费空间。

  • 如果全局变量加以static关键字修饰,则为静态全局变量,作用域局限在定义它的文件内;
    好处是:1.不会被其他文件访问和修改;2/其他文件中可以使用相同名称的变量,不会发生冲突。

  • static关键字修饰函数也是如此,加上后只能限定在定义它的文件内被调用
    好处是:1.不会被其他文件访问; 2.其他文件中可以使用相同名称的函数,不会发生冲突。

  • 上文总结:(函数内的变量而言)
    局部变量生存期最短,用时活,用完死。
    静态局部变量到数第二,生存期为整个程序的生命周期,但限制了作用域;

  • 全局变量和静态局部变量如果没有被初始化,编译器自动将其初始化为0;

  • 非静态局部变量如果没有被初始化,则它的值是随机的。

  • 允许全局变量和局部变量同名,但在局部变量的作用域内访问的是局部变量,此时全局变量被屏蔽。

  • C语言由源代码生成可执行文件的各阶段如下:C源程序->编译预处理->编译->优化程序->汇编程序->链接程序->可执行文件。通常将C源程序->编译预处理->编译->优化程序->汇编程序称为编译阶段;而把链接程序生成可执行文件这一阶段称为链接阶段。

  • 伪指令(以#开头的指令)

  • 预处理过程会删除程序中的注释和多余的空白字符

  • <>尖括号括起来的头文件,这种格式告诉预处理程序在编译器自带的或外部库的头文件中搜索被包含的头文件。

  • “ ”双引号把头文件括起来。这种格式告诉预处理程序在当前被编译的应用程序的源代码文件中搜索被包含的头文件,如果找不到,再搜索编译器自带的头文件。

  • 宏定义, #define 宏标识符 宏标识符代表的特定的字符串;使用宏由如下好处:
    1.使用方便 2.可读性强 3.容易修改
    所以宏标识符要尽可能取得见名知义,增强可读性;宏定义尽量集中到源程序得最前面,便于修改。

  • 宏定义可以嵌套,但长表达式必须加括号,不然难以保证宏和参数得完整性。

错误例子
#define CUBE(x) x * x * x    正确例子
#define CUBE(x) ((x) * (x) * (x)) 这是因为带参宏的定义使得后续必须如此定义,否则使用不当,会出现一些无法预估的错误
  • 宏调用比函数调用的执行效率高,但由于带参数的宏很容易发生副作用,所以并不推荐带参数的宏大量使用。
  • #undef取消宏定义,取消后不能再调用,否则出错。

例5-22 条件编译指令的用法

  • 先看现象

程序运行时,定义了DEBUG符号,所以处于自定义的调试状态;
在循环中会输出每一步的 i 和 sum 的值,暂停并提示按任意键继续;
这样就可以清楚地看到每一步循环地执行状态。达到调试程序的目的。
因为最后会学习八种常见排序,所以笔者会在演示排序中利用该指令。
百度百科链接:link.
在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>#define DEBUGint main(void)
{int i;int sum = 0;//#undef DEBUGfor (i = 1; i <= 10; i++){#ifdef DEBUGprintf("i = %d, sum = %d", i, sum);system("pause");#endifsum = sum + i;}printf("Sum is : %d\n", sum);return 0;
}

课后练习

5-11.
利用递归从前往后输出整数的各位

#include <stdio.h>void p(int);int main(void)
{int n;printf("请输入一个整数:");scanf("%d", &n);p(n);
}void p(int n)
{if (n / 10 == 0){printf("%d ", n);return;}p(n / 10);printf("%d ", n % 10);
}

5-12.
利用非递归和递归进行因式分解

#include <stdio.h>void factor(int);
void factorr(int);int main(void)
{int n;printf("请输入待分解的整数:");scanf("%d", &n);printf("\n非递归分解:%d = ", n);factor(n);printf("\n递归分解:%d = ", n);factorr(n);return 0;
}//非递归分解方法void factor(int n)
{int i = 2;if (n < 0){n = -n;}while (n >= 2){for (i = 2; i <= n; i++){if (n % i == 0){if (n != i){printf("%d * ", i);}else{printf("%d", i);}n = n / i;i = 2;break;}}}
}//递归分解方法void factorr(int n)
{int i;if (n < 0){n = -n;}for (i = 2; i <= n / 2; i++){if (n % i == 0){printf("%d * ", i);factorr(n / i);return;}}printf("%d", n);
}

数组:(7.12)

基础知识

每天两小时学习,个人的角度学习基础知识,就是反复的对自己进行洗脑。

学习目标

  • 理解数组的概念
  • 初步掌握C语言中数组元素的存储特点
  • 初步掌握一维,二维数组的定义,初始化,引用及与函数的关系。
  • 初步掌握字符数组处理字符串的方法
  • 初步领悟数组作为顺序存储数据的工具。

主要内容
一维数组和二维数组的定义,初始化,元素的引用,简单介绍数组与函数的关系。
初步了解数组的存储;并将字符串的输入/输出,常见操作单独展开了简单的介绍。
介绍了选择排序,顺序查找的算法。

------------------------------------------数组的定义-----------------------------------------------

  • 定义一个数组,需要指定元素的类型和元素的数量,如下为一般格式:
元素类型名 数组名[数组长度];
注意1[]中必须是大于0的整数常量,不能用变量指定。(gcc编译能通过,但实际少用)
注意2:在定义处的[]中存放表示数组大小的 常量 表达式;
注意3:在非定义处[]中存放表示元素下标的值。(可以是常量或变量,或整型表达式)
注意4:定义后,数组名是常量,值 为第一个元素的首地址,通常称为数组的基地址。
注意5:一维数组的总字节数=sizeof(元素类型名) * 数组长度
注意6:数组下标从 0 开始,毋庸置疑。
注意7:无论测试还是书籍中,C99中可以存在int n=3;int a[n];这也是注意1后括号笔者所述内容;
接上7:但仍然建议用常量作为数组长度。(笔者认为C语言还是相信经验丰富的前辈比较好!)
  • 当定义了int array[10];后,0-9 是有效下标,而a[10]无效,但编译器不会帮你检查下标越界问题。
  • 查看linux系统位数 uname -i
  • 系统为数组申请 数组长度 * sizeof(元素类型名) 个连续的内存单元,用来存储数组元素;
    内存的大小取决于数组的类型及数组长度。
    如果第一个元素所占的存储单元首地址为addr,
    则第二个元素所占的存储单元首地址为 addr+sizeof(元素类型名)
    同理,下标为 i 的元素的首地址应该为 addr+ i * sizeof(元素类型名)

------------------------------------------初始化一维数组-----------------------------------------------

  • 如果数组在定义时元素未初始化(全局数组除外,全局变量未初始化编译器自动补值为0),或之后也没有给元素赋值,则这些元素的值就是垃圾值。
1.可以逐个元素赋值(循环语句),效率低下
2.完全初始化: int a[5] = {12345};
3.省略长度的初始化:int a[]={1,2,3,4,5};(与完全初始化等阶)
4.不完全初始化:int a[5] = {1,2,3}; (未被初始化元素的值为0), int a[5]={0};(数组所有元素值均为0)

注意上述初始化 2 和 3, 括号内容(与完全初始化等阶),记住这句话,因为在sizeof(a[])的时候时按照初始化的元素个数*类型来计算的。而存入该数组元素的上限也与初始化相关。
举例: int a[]={0},只占4个字节, 且存入数值时只有a[0]有效, (已经测试过)

  • 完全初始化后,可以利用 sizeof(a) / sizeof(int) 计算数组中元素个数。
  • 错误1:int a[5]={0},b[5]; b = a; 不可以把数组a 的值全部赋值给数组b
    数组名代表的是数组第一个元素的首地址,是常量,即数组名不能作为左值(不能出现在赋值号左边)

------------------------------------------通过函数访问一维数组-----------------------------------------------

  • 如下三种无返回值方式,这三种方式结果一样;
    因为每种方式都告诉编译器要接收一个数组的首地址。
    对应的实参均可以为 (数组名,元素个数)
1.形参时一个已定义大小的数组的函数原型:
void MyFunction(int arr[10],int size);2.形参时一个未定义大小的数组的函数原型:
void MyFunction(int arr[],int size); (初始化数组时说到,省略长度的初始化与完全初始化等阶)3.形参是一个指针的函数原型
void MyFunction(int *arr,int size);

------------------------------------------一维数组的简单应用-----------------------------------------------

  • 一维数组可用于描述线性事物,可以处理一个行向量或一个列向量的数据。(排序和查找 常用)
    1.求最大数及位置 (对于一组没有给定取值范围的数据,不能初始假设最大值为0.)
    2.排序
    3.查找 (最常用的是“顺序查找”,但有更高效的)
    (如上内容举例暂时省略,先记住用途)

------------------------------------------二维数组定义-----------------------------------------------

  • 二维数组常用来表示一个矩阵;
  • 定义格式:类型说明符 数组名[常量表达式1][常量表达式2]
    常量表达式1表示 第一维的长度(行数),常量表达式2表示第二维的长度(列数)。(行下标,列下标)
    元素数 = 常量表达式1 * 常量表达式2所占内存 = 元素数 * 元素类型
    比如 int a[3][4];12个元素,48字节;
    接上例: a[3][4]分解为三个一维数组,其数组名为a[0],a[1],a[2]; 每个一维数组都有4个元素
    一维数组 a[0]的元素为:a[0][0], a[0][1], a[0][2], a[0][3] (其它两个类似)
  • 数组的元素在内存中是连续存放的。而C语言的二维数组是按行优先存储的。先a[0],再a[1]…
  • 若二维数组是 int a[M][N],即 M 行 N 列,则元素a[ i ][ j ]的内存单元的首地址为 a + (i * N + j) * 4

------------------------------------------二维数组引用-----------------------------------------------

  • 与一维元素的引用方式相同,元素只能单个引用不能整体引用,引用时只需再数组名后加上其下标。
  • 对于二维数组元素的输入及输出通常使用双重循环实现,外层循环控制行下标,内层循环控制列下标。

------------------------------------------二维数组初始化-----------------------------------------------

  • 二维数组可按行分段赋值,也可按行连续赋值。
1.按行分段赋值
int a[2][3] = {{80,76,92},{61,65,71}};2.按行连续赋值可写成:
int a[2][3] = {90,76,92,61,65,71};如上两种赋初值的结果是完全相同的3.可以只对部分元素赋初值,未赋初值的元素自动取0值。(数组的初始化讲过了)4.如果对全部元素赋初值,则第一维的长度可以不给出。
例如: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};
但是不能写成:int a[3][]; 笔者认为这个错误是,编译器无法识别数组的边界导致的。

------------------------------------------二维数组应用-----------------------------------------------

  • 二维数组作为函数的形参定义形式为:
    类型标识符 数组名[一维长度][二维长度] 或 类型标识符 数组名[ ][二维长度]

------------------------------------------字 符 串-----------------------------------------------

  • 只有以’\0’(空字符)结尾的字符数组才是C字符串,否则只是一般的C字符数组。
    而’\0’是 ASCII 值为 0 的不显示字符。
  • 字符串的初始化可以使用“=”进行初始化,如下:
char str1[] = "abcde";
char* str3 = "abcdefg"; 
错误案例如下:
str2[20];   str2 = "xyz"; 错因:非定义处不能利用 “ = ” 对C字符串进行赋值,因为数组名是常量。
  • 若事先知道字符串最多有 N 个字符,则存放字符串的数组长度至少为 N+1;
  • C中字符串 常用的几个简单函数:
int strlen(const char * str)  返回字符串str长度
char* strcat(char* dest,const char* src) 将字符串src附加到dest后,返回dest;
char* strcpy(char* dest,const char* src) 将字符串src复制到dest中,返回dest;
int strcmp(const char* str1,const char* str2) 字符串比较函数, 相等返回0,前大返回正,后大返回负;

洗脑内容

  • 一维数组可以模拟线性事物
  • 二维数组可以模拟平面事物
  • 三维数组可模拟立体事物,利用数组可以模拟现实世界。(之前知识匮乏,只能在想象中感受这点。)

例6-2 将一组整数逆置:输入n(n<=10)及n个整数,将这组整数逆置并输出。

源代码给出的思路是,正常存入,再逆置;
如果只是完成需求,可以逆置存入,最后打印;

#include <stdio.h>const int N = 10;int main(void)
{int a[N];              				//定义有N个整数元素的数组aint n;int i; scanf("%d", &n);       				//输入整数个数for(i=0; i < n; i++)   		//输入数组a的n个元素 scanf("%d", &a[i]);  			//输入元素a[i], 注意它是a的第i+1个元素 for(i=0;i < n/2;i++)  			//逆置,距离首(a[0])和尾(a[n-1])相等的元素交换其值{int t;t = a[i];  a[i] = a[n-1-i];  a[n-1-i] = t;	//交换a[i]与a[n-1-i]的值 }for(i = 0;i < n;i++)    			//输出a的n个元素 printf("%d  ",a[i]);                   return 0;
}

现象:
(笔者认为可以在存入第n个数据时提醒)
在这里插入图片描述

例6-3

题目:已知N个学生(N<=10)的年龄,输出平均年龄以及大于平均年龄的学生数/

书籍本身给出的代码是.cpp文件,是C++的逻辑自下而上,面向对象。
而C语言的逻辑自顶而下,面向过程。
不管顺序如何,并不影响笔者学习编程的思想。

分析:
1.N个学生年龄已知,构建数组存储N个学生年龄。(实际这部分内容是输入获取的)
2.求平均值。(double类型精度最高)
3.输出大于平均年龄的学生数量 。(比较)

#include <stdio.h>int Input(int arr[]);                  		//输入数组arr的元素,返回元素个数 
double GetAverage(int arr[], int size);   	//返回数组中size个元素的平均值 
int Count(int arr[], int size, double ave);  	//返回数组中size个元素中大于ave的元素个数 
const int N=10;int main (void)
{int age[N], n, k;     					//分别存储年龄、实际学生数,以及大于平均年龄的学生数double ave;                				//存放学生的平均年龄	n=Input(age);              				//输入学生年龄,并求学生数nave = GetAverage(age, n);    			//求n个学生平均年龄k=Count(age, n, ave);        				//求大于平均年龄的学生数printf("平均年龄是:%.1f\n大于平均年龄的学生数是:%d\n", ave, k); return 0;
}
int Input(int arr[])
{int n = 0, a;               				//存储学生个数及学生的年龄while(1){scanf("%d", &a);if(a <= 0 ) break;   				//年龄不合法,结束输入 arr[n++] = a;     					//将a赋值给下标为n的元素,同时学生数加1}return n;	
} 
double GetAverage(int arr[], int size)
{int  i;double ave, sum = 0;for (i = 0; i < size; ++i){sum += arr[i];}	ave = sum / size;return ave;
}
int Count(int arr[], int size, double ave)
{int k = 0, i;	            				//存储值大于ave的元素个数for(i = 0; i < size; i++){if(arr[i] > ave)     k++;      		//元素值大于ave时,k增加1 }return k;                      			//返回k
}

例6-8 字符串的简单加密

  • gets从标准输入设备读字符串函数,其可以无限读取,不会判断上限,以回车结束读取;
    gets函数 百度百科链接link.
  • 常用的scanf 是遇到空格结束读取。
#include <stdio.h>
#include <string.h>int main(void)
{char text[80];int len;              					//存放串text的长度 	printf("输入要加密的字符串:");gets(text);           					//输入可能含有空格的字符串len = strlen(text);     					//求字符串的长度int i;for(i = 0; i < len; i++){//加密处理 if(text[i] >= 'a'&&text[i] < 'z' || text[i] >= 'A' && text[i] < 'Z') text[i]++;else if(text[i] == 'z') text[i] = 'a';else if(text[i] == 'Z') text[i] = 'A';} 	printf("加密后字符串为:    %s\n", text);return 0;	 
}

例6-9 系统登陆验证

这代码笔者也写过类似的,但水平太低就不放出来了

分析:假设用户id由不超过30个任意字符组成,密码由不超过20个任意字符组成,目前系统只有一个用户id是wyp,对应密码是123456,使用gets(str)函数,输入id和密码;然后使用函数strcmp判断id和密码是否相同。输入三次均没有输入正确则退出登陆界面。

#include <stdio.h>
#include <string.h>int main(void)
{//正确的id号和密码分别为:"wyp", "123456" char id[31], psw[21];  			//存放用户输出的id和密码int n=3, f=0;  					//分别存放输入id、密码的次数,以及是否输入正确,0表示不正确 do{n--;printf("输入你的id:");gets(id);printf("输入你的密码:");gets(psw);if(strcmp(id,"wyp") == 0 && strcmp(psw,"123456") == 0) { //验证id和psw与系统设定的用户和密码是否完全一致 printf("welcome!\n");f = 1;          				//标志输入正确 break;}else{if(n > 0)printf("你还有%d机会输入id和密码哟!\n", n);}}while(n > 0);if(f == 0)              			//三次输入均不正确printf("sorry! bye bye!\n");	return 0;
}

课后练习

1.C语言中,引用数组元素时,其数组下标的数据不正确的是( C )。
A.整型常量 B.整型表达式
C.整型常量或整型表达式 D.任何类型的表达式

2.以下对一维整型数组a正确定义的是( D )。
A.int a(10); B.int n=10,a[n];
C.int n; scanf("%d",&n);int a[n]; D.#define SIZE 10 int a[SIZE];

3.若有语句: int a[10];则对a数组元素的正确引用是( D )。
A.a[10] B.a[3.5] C.a(5) D.a[10-10]

4.若有语句:int a[3][4];则对a数组元素的正确引用是( C )。
A.a[2][4] B.a[1,3] C.a[1+1][0] D.a(2)(1)

5.若有语句:int a[3][4];则对a数组元素的非法引用是( D )。
A.a[0][2*1] B.a[1][3] C.a[4-2][0] D.a[0][4]

6.以下能对二维数组a正确初始化的语句是( BD )。
A.int a[2][ ]={{1,0,1},{5,2,3}}; B.int a[ ][3]={{1,2,3},{4,5,6}};
C.int a[2][4]={{1,2,3},{4,5},{6}}; D.int a[ ][3]={{1,0,1},{ },{1,1}};

7.下面程序以每行4个数据的形式输出a数组,请填空。

#include<stdio.h>
#define N 20int main(void){ int a[N],i;for{i=0;i<N;i++}  scanf("%d",   &a[i]      );for{i=0;i<N;i++}{ if(   (i+1)%4==0   ) ;printf("%3d ",a[i]);}printf("\n");return 0;
}

8.下面程序的运行结果是( )。

#include<stdio.h>
int main(void)
{    char str[ ]="SSSWLIA",c;int k;for(k=2;(c=str[k])!='\0';k++){switch(c){  case'I':++k;break;case'L':continue;default:putchar(c);continue;}putchar('*');}return 0;
}
//运行结果为: SW*

9.数组可以用来保存很多数据,但在一些情况下,并不需要把数据保存下来。下面哪些题目可不借助数组?哪些必须借助数据?均编程实现。
(1)输入一些整数,统计个数。
(2)输入一些整数,求最大值、最小值及平均数。
(3)输入一些整数,判断哪两个数最接近。
(4)输入一些整数,求第二大的值。
(5)输入一些整数,求它们的方差。
(6)输入一些整数,统计不超过平均数的个数。
参考代码如下:

1)可不借助数组
#include <stdio.h>int main(void)
{int x,n = 0;printf("输入正整数,-1输入结束\n");while(1){scanf("%d",&x);if(x<0) break;n++;}printf("%d\n",n);return 0;	
}2)可不借借助数组
#include <stdio.h>int main(void)
{int x,max,min,n = 0;double sum = 0;printf("输入正整数,-1输入结束\n");scanf("%d",&x);max = min = x;while(1){scanf("%d",&x);if(x<0) break;sum += x; if(x>max) max =x;if(x<min) min = x; n++;}printf("最大数为:%d\n",max);printf("最小数为:%d\n",min);printf("平均数为:%.2f\n",sum/n);return 0;	
}
3)借助数组
#include <stdio.h>
#include <stdlib.h>
int cmp(const void *a,const void *b)
{return *(int *)a -*(int *)b;
}
int mindiff(int *a,int n);
int main(void)
{//5 100 78 3 77 -1int x,n = 0;int a[100];	printf("输入正整数,-1输入结束\n");while(1){scanf("%d",&x);if(x<0)  break;a[n++] = x;	}qsort(a,n,sizeof(a[0]),cmp);	int k = mindiff(a,n);printf("相差最小的两个元素为:%d %d\n",a[k],a[k+1]);return 0;	
}
int mindiff(int *a,int n)
{int min = 32767,k;for(int i=0;i<n-1;i++){if(fabs(a[i]-a[i+1])<min){min = fabs(a[i]-a[i+1]);k = i;} 			}	
return k;
}4)借助数组
#include <stdio.h>
#include <stdlib.h>
int cmp(const void *a,const void *b)
{return *(int *)a -*(int *)b;
}int main(void)
{//5 100 78 3 77 -1int x,n = 0;int a[100];	printf("输入正整数,-1输入结束\n");	while(1){scanf("%d",&x);if(x<0) break;a[n++] = x;	}qsort(a,n,sizeof(a[0]),cmp);	printf("第二大的数为:%d\n",a[n-2]);return 0;	
}
5)借助数组
#include <stdio.h>
#include <stdlib.h>
int cmp(const void *a,const void *b)
{return *(int *)a -*(int *)b;
}int main(void)
{int x,n = 0;int a[100];	printf("输入正整数,-1输入结束\n");	while(1){scanf("%d",&x);if(x<0) break;a[n++] = x;	}qsort(a,n,sizeof(a[0]),cmp);	printf("第二大的数为:%d\n",a[n-2]);return 0;	
}
6)借助数组
#include <stdio.h>
#define N 100
int main(void)
{ int age; int sage[N];           double sum = 0;    int n = 0;         while(1)  {scanf("%d",&age);   if(age <= 0) break;    sum += age;sage[n]=age;          n++;}int k = 0;if(n > 0){printf("%.2f\n",sum/n);for(int i=0;i<n; i++)if(sage[i]<=sum/n)   k++;printf("%d\n" , k);}	        return 0;	
}

10.年龄与疾病
描述:某医院想统计一下某项疾病的获得与否与年龄是否有关,需要对以前的诊断记录进行整理,按照018、1935、36~60、61以上(含61)四个年龄段统计患病人数占总患病人数的比例。
输入:共2行,第一行为以往病人的数目n(0<n≤100),第二行为每个病人患病时的年龄。
输出:按照018、1935、36~60、61以上(含61)四个年龄段输出该段患病人数占总患病人数的比例,以百分比的形式输出,精确到小数点后两位。每个年龄段占一行,共四行。
样例输入:
10
1 11 21 31 41 51 61 71 81 91
样例输出:
20.00%
20.00%
20.00%
40.00%
参考代码如下:

//0-18、19-35、36-60、61
#include <stdio.h>
int main(void)
{int age,n,num[4]={0};scanf("%d",&n);for(int i=0;i<n;i++) {scanf("%d",&age);if(age>=61) num[3]++;else if(age>=36) num[2]++;else if(age>=19) num[1]++;else num[0]++;}for(int i=0;i<4;i++){printf("%.2f%%\n",100.0*num[i]/n);}return 0;
} 

11.人民币支付
描述:从键盘输入一个指定金额(以元为单位,如345),然后输出支付该金额的各种面额的人民币数量,显示100元、50元、20元、10元、5元、1元各多少张,要求尽量使用大面额的钞票。
输入:一个小于1000的正整数。
输出:输出分行,每行显示一个整数,从上到下分别表示100元、50元、20元、10元、5元、1元人民币的张数。
样例输入:
735
样例输出:
7
0
1
1
1
0
参考代码如下:

#include <stdio.h>
int main()
{//从上到下分别表示100元,50元,20元,10元,5元,1元人民币的张数int a[]={100,50,20,10,5,1};int y,n;scanf("%d",&y);n=sizeof(a)/sizeof(int);for(int i = 0;i < n;i++){printf("%d\n",y / a[i]);y%=a[i];}	return 0;
} 

12.最简真分数
描述:给出n个正整数,任取两个数分别作为分子和分母组成最简真分数,编程求共有几个这样的组合。
输入:第一行是一个正整数n(n≤600)。第二行是n个不同的整数,相邻两个整数之间用单个空格隔开。整数大于1且小于等于1000。
输出:一个整数,即最简真分数组合的个数。
样例输入:
7
3 5 7 9 11 13 15
样例输出:
17

参考代码如下:

#include <stdio.h>
#include <stdlib.h>int zhenfen(int m,int n);//m和n能构成真分数返回1,否则返回0 
int main()
{int n,*a,i,j,k;scanf("%d",&n);a=(int *)malloc(sizeof(int)*n);for(i=0;i<n;i++){scanf("%d",&a[i]);}k = 0;for(i=0;i<n-1;i++){for(j=i+1;j<n;j++){if(zhenfen(a[i],a[j])) k++;}}printf("%d\n",k);free(a);return 0;	
}
int zhenfen(int m,int n)
{int r;while(m%n){r = m%n;m = n;n = r;}if( n == 1) return 1;return 0;
}

指针:(7.13)

基础知识

每天两小时学习,从我个人的角度来学习基础知识,就是反复的对自己进行洗脑。

学习目标

  • 理解地址与指针的概念。
  • 熟练掌握指针的定义和使用。
  • 掌握指针与数组的关系。
  • 掌握指针与函数的关系。
  • 掌握动态内存分配的概念及相关库函数。
  • 掌握命令行参数的概念。

内容

  • 指针就是内存地址,指针变量就是存储地址的变量。
  • 使用指针可以提高程序的编译效率和执行速度,使程序更加简洁;
  • C语言提供两种指针运算符 “*” 和 “&”

------------------------------------------指针变量定义-----------------------------------------------

1.数据类型不是指针变量的数据类型,而实其所指目标对象的数据类型。
数据类型 * 变量名 [=初值];
例如:int *p;告诉编译器,p变量只能存储整型空间的地址,不能存储其他类型空间的地址。
  • 取地址运算符 & :例如: p = &a; 表面得到变量a的地址,并把该地址存入指针变量p中。
  • 间接运算符 *。星号(*)如果不是再指针变量定义时出现,而是某条语句某个指针变量前出现,则是间接运算符,表示 取指针所指向变量的值。
  • 指针变量空间的大小。定义指针变量后,系统会为该指针变量分配存放一个地址值存储单元,存储单元的大小与该指针所指向内存空间的类型无关一般情况下,32位系统分配4个字节,64位系统分配8个字节,可以用sizeof运算符计算出指针变量所占空间大小。

------------------------------------------空指针-----------------------------------------------

  • 空指针常量是一个值为0的整数常量表达式,在头文件stdlib.h以及其他头文件中,宏NULL被定义为空指针常量。
int *ptr = NULL; 定义一个空指针

------------------------------------------void 指针-----------------------------------------------

  • 指向void的指针,简称void指针。
  • void指针是类型为void* 的指针,表示未确定类型的指针,也称作万能指针
  • 若想声明一个可以接收任何类型指针参数的函数,可以将所需的参数设定为void* 指针。

------------------------------------------void 指针 与 memset 函数-----------------------------------------------

  • 函数 memset() ,声明在string.h 中,原型:void* memset(void *s, int c, size)
  • 函数memset()将 c 的值赋值到 a 数组的每个字节,实参 a 具有int * 类型;
  • 函数被调用时,实参被转换成形参void*,这个类型转换是隐式的。
  • memset()函数常被用来对数组元素清0,如下:
int a[10];
memset(a,0,10 * sizeof(int));

------------------------------------------void 指针 与 malloc 函数-----------------------------------------------

  • malloc 全称 memory allocation ,中文叫动态内存分配。
  • 用于申请一块连续的指定大小的内存块区域,以void* 类型返回分配的内存区域地址
  • 当无法知道内存具体位置的时候,想要绑定真正的内存空间,就需要用到动态分配的内存。
  • void* 类型可以通过类型转换强制转换为任何其他类型的指针。
  • malloc函数的原型:void* malloc(size_t size);
  • 如果分配成功则返回指向被分配内存的地址(此存储区中的初始值不确定),否则返回空指针NULL。
  • 如果内存不再使用时,应使用 free() 函数将内存块释放;原型 void free(void* ptr)
  • 结合如上两个函数就可以使用动态数组,也就是在程序运行过程中,根据需要动态申请数组空间,不需要时再释放数组空间。
  • 查看例 7-3 学习如何使用。

------------------------------------------const 指针常量-----------------------------------------------

  • const修饰“*” 被称作 常量指针,这样不能通过该指针变量修改指向的内容。
					常量指针改指针。意思是可以修改指针,但不能修改指针指向的变量。
int x = 5,y=6;
const int *ptr = &x;
*ptr = 10; 			错误,不能通过常量指针修改所指内容。
x = 10;    			正确。
ptr = &y;  			正确,因为ptr本身是常量,可以指向其他整型变量。

------------------------------------------常量指针变量-----------------------------------------------

  • 用const修饰指针变量名,称为常量指针变量。
int x=5,y=6;
int * const ptr = &x;
*ptr = 10;				正确,可以通过ptr修改指向的数据。
ptr = &y;				错误,不能修改ptr的值,因为ptr本身是常量。

------------------------------------------指针常量-----------------------------------------------

  • 指针常量既是常量指针,又是常量指针变量。
int x = 5,y = 6;
const int * const ptr = &x;
*ptr = 10;					错误,不能通过常量指针修改所指内容。
ptr = &y;					错误,不能修改ptr的值,因为ptr本身是常量。

------------------------------------------指针与数组-----------------------------------------------

  • 利用数组的存储方式,计算机只需知道第一个数组元素的地址,就可以访问整个数组。例 7-6
  • 函数形参是指针类型的,编程实例 7-7

------------------------------------------数组指针-----------------------------------------------

  • 指向数组的指针被 简称为 数组指针
  • 一维数组指针的定义形式为: 类型名( * 标识符)[数组长度];
int (*p)[10];
P是一个指针变量,指向一个长度为10,数组元素为int类型的一维数组;int a[10];
int (*p)[10] = &a;
a 是有10个单元的整型数组,p指向了这个数组。 为什么不是 P = a 呢?
因为 a 是 a[0] 单元的地址,是一个整型空间的地址,与 p 类型不匹配。int a[11];
int (*p)[10] = &a; 错误,p 只能是10个整型空间的地址,不能是其它类型的地址。
  • 数组指针的主要用途是指向二维数组的某一行。 如例 7-8

------------------------------------------指针数组-----------------------------------------------

  • 指针数组也就是元素为指针类型的数组。一般情况,数组中的指针会指向动态分配的内存区域。
  • 一维指针数组的定义形式为:类型名 *标识符[数组长度];编程实例 例7-9
int *ptr[10]; 
ptr 是数组名,10个元素的类型都是 int *
  • 指针数组通常也适用指向若干字符串,这样使得字符串处理更加灵活方便;
    (其实笔者更推荐枚举类型)
    ------------------------------------------指向函数的指针-----------------------------------------------

  • 函数包括一系列的指令,当它经过编译后,在内存中会占据一块内存空间,该空间有一块内存空间,该空间有一个首地址,指针变量可以存储这个地址。
    存储这个地址的变量就是函数指针(或称为指向函数的指针)
    也可以在数组中存储函数指针,然后使用数组的索引来调用这些函数。

  • 函数指针的定义格式如:数据类型 ( * 指针名)(参数列表);
    例如:double (*funcPtr)(double,double);(定义函数指针括号不能省略,否则变成了函数声明)
    funcPtr就是函数指针,而该指针只能指向有两个double形参且返回值为double的函数。

  • 举例说明 例 7-10

  • 函数指针还可以作为函数的形参,最典型的是 stdlib.h 中有一个qsort() 函数,可以对数组进行排序。

  • qsort 函数百度百科链接

void qsort(void* base,size_t num,size_t size,int (*compar)(const void*const void*));
函数原型看着很复杂,一共四个参数
1.base是void指针,可以指向待排序数组的起始位置
2.num是排序的元素个数
3.size是每个元素占的字节数
4.compar则是函数指针,它指向的函数可以确定元素的顺序。
举例说明,请看下文中的例 7-12

------------------------------------------命令行参数-----------------------------------------------

  • 命令行参数了解链接

洗脑内容

  • 指针变量定义时,如果没有初始化,指针变量的值是未定义的。(一般情况下,定义指针应该初始化)
  • 常量指针改指针
  • 右左法则,const最近的 则不能修改。
  • 难以判断类型的请 参考 右左法则 ;百度百科链接:link.
  • 当一个指针指向普通数据变量时称为一级指针,指向一级指针的指针是二级指针,指向二级指针的指针是三级指针。多级指针常与多维数组一起使用。
  • 指针内容核心指针就是地址,指针变量就是存储地址的变量

例7-3 随机生成指定长度的字符串。

  • 通过随机生成指定长度字符串,介绍 malloc 函数和 free 函数具体怎么使用
  • buffer 是动态字符数组,用于存储字符串
  • 例 7-4 也是动态数组的例子
#include <stdio.h>      
#include <stdlib.h>     // malloc, free, rand,srand 
#include <time.h>       // time(0)int main ()
{int len;char * buffer = NULL;     //声明指针变量并初始化为空指针srand(time(0)); // 设置随机数种子 printf ("你想要多长的串? ");scanf ("%d", &len);buffer = (char*) malloc (len+1);     //动态分配 len+1个字节空间 if (buffer == NULL) exit (1);          //分配失败 for (int i = 0; i < len; i++)               //产生随机串 buffer[i] = rand()%26 + 'a';buffer[len]='\0';                               //放字符串结束标志 printf ("随机串: %s\n",buffer);free (buffer);  //释放空间 return 0;
}

例7-4 与指定数字相同的数的个数

  • 一维动态数组
  • 一般情况下,结束程序运行前,要使用free()函数释放空间,因为动态分配的内存空间,操作系统不能自动收回。
#include <stdio.h>
#include <stdlib.h>
int main( void )
{int n;int *a = NULL;       //定义指针变量并初始化为空指针scanf("%d",&n);     a = (int*)malloc( n*sizeof(int) );  //动态分配 n个整型空间for(int i=0;i<n;i++)scanf("%d",&a[i]);int x,sum = 0;scanf("%d",&x);for(int i=0;i<n;i++)if(x == a[i])   sum++;printf("%d\n",sum);free(a);                        //释放a指针指向的n个整型空间 return 0;
}

例7-6 通过指针操作数组。

  • 格式控制符“%p”中的 p 是pointer(指针)的缩写。指针的值是C语言实现(编译程序)相关的,但几乎所有实现中,指针的值都是一个表示地址空间中某个存储器单元的整数。printf函数中对于%p一般以十六进制整数方式输出指针的值,附加前缀0x。
  • %p是打印地址的, %x是以十六进制形式打印, 完全不同!另外在64位下结果会不一样, 所以打印指针老老实实用%p .
    在这里插入图片描述
#include <stdio.h>int main()
{int a[5] = {1,3,5,7,9};int i = 0 ;int *p = a;p[2] = 10;  printf("a数组的首地址是:%p\n",a); for(i = 0;i < 5;i++)   //使用指针变量p输出数组a每个单元的地址及数组元素值 printf("a[%d]的地址是:%p a[%d]的值是:%d\n",i,p+i,i,*(p+i));double x;double *q =  &x;printf("%p  %p\n",q,q+1);	return 0;
}

例7-7 在数组中查找元素

  • search 中 for 循环里 的 if 判断条件 相当于 p = a;这时就可以用 p 作为数组名来操作数组,但是这的前提是你已只给指针赋值的地址是数组首地址,如果不是,操作失败。
#include <stdio.h>int search(const int *p, int n,int x);//函数声明  int main()
{int a[6] = {1,5,2,3,9,7};int x;printf("输出要查找的元素:");scanf("%d",&x);int k = search(a,6,x);if(k == -1)printf("未找到!\n");else printf("找到了,是数组中的第%d个元素:",k+1);return 0;
}int search(const int *p, int n,int x)
{//在数组中找元素值为x的元素//找到返回在数组中的下标,找不到返回-1 int pos = -1;int i = 0; for(;i < n;i++){if(p[i] == x) {pos = i;break;}}return pos;
}

例7-8 数组指针访问二维数组

#include <stdio.h>int main(void)
{int a[5][3] = { {1,2,3}, {4,5,6}, {7,8,9}, {10,11,12}, {13,14,15} };int (*p)[3] = a;     // 指向第一行int sum = 0;for(int i = 0;i<5;i++){for(int j=0;j<3;j++)sum+= *(*p+j) ;p++;               //指向下一行}printf("sum = %d\n",sum);return 0;
}
  • 数组指针更多地应用在函数形参,二维数组名作为实参。上述程序改写为如下程序:
#include <stdio.h>
int sum(int (*p)[3],int n);
int main(void)
{int a[5][3] = { {1,2,3}, {4,5,6}, {7,8,9}, {10,11,12}, {13,14,15} };printf( "sum = %d\n", sum(a,5) );       //函数调用,二维数组名作为实参return 0;
}
int sum(int (*p)[3],int n)
{int s = 0;for(int i = 0;i<5;i++){for(int j=0;j<3;j++)s += *(*p+j) ;p++;               //指向下一行}return s;
}

例7-9 指针数组编程示例

  • 个人感觉指针数组不是很友好,得初始化,得申请空间,正常得话还得加个失败判断。
  • 代码中p[0]是一维动态数组(7个整型单元)的起使地址
  • p[1]是一维动态数组(5个整型单元)的起使地址
  • p[2]是整型变量x的地址
    在这里插入图片描述
#include <stdio.h>
#include <stdlib.h>int main(void)
{int x = 5;int *p[3] = {NULL,NULL,NULL};p[0] = (int *)malloc(7*sizeof(int));p[1] = (int *)malloc(5*sizeof(int));p[2] = &x;for(int i = 0;i < 3;i++){printf("%#X\n",p[i]);}return 0;
}

例7-10 函数指针示例

在这里,函数名单独拿出来的用法和数组名类似

#include <stdio.h>double Add(double x,double y)
{return x + y;
} 
int main (void)
{double (*funcPtr)(double ,double );   //函数指针声明funcPtr = Add;                                   // funcPtr指向函数Adddouble result = funcPtr(6.0,7.0);       //通过函数指针调用函数printf("%f",result);return 0;
}
  • 函数指针变量还可以指向其他同类型的函数,以增加程序设计的灵活性,如下例7-11

例7-11 对用户输入的两个数字,进行加减乘除计算

  • 这个例子就是一个简单的计算器。
  • 表达式funcTable[i](x,y) 会调用地址保存在 funcTable[i] 中的函数,结果如下:
    在这里插入图片描述
#include <stdio.h>double Add(double x,double y);
double Sub(double x,double y);
double Mul(double x,double y);
double Div(double x,double y); double (*funcTable[4])(double,double) = {Add,Sub,Mul,Div};      //函数指针数组
char *msgTable[4] = {"sum","Difference","Product","Quotient"};  //字符指针数组
int main(void)
{double x = 0, y = 0;printf("输入两个运算数:\n");scanf( "%lf %lf",&x,&y) ;for(int i =0;i < 4;i++)   //遍历函数指针数组,完成加减乘除运算printf("%10s: %6.2f\n",msgTable[i],funcTable[i](x,y));return 0;  
}double Add(double x,double y)
{return x + y;
}
double Sub(double x,double y)
{return x - y;
}
double Mul(double x,double y)
{return x * y;
}
double Div(double x,double y)
{return x / y;
}

例7-12 使用qsort()函数完成数组排序

  • 该程序是对整型数组排序.如果对其他类型的数组排序,还需要定义一个相应类型的两个数的比较函数。
  • qsort() 函数的形参base是void指针,而compare是函数指针,才让qsort() 函数具有通用性,可以对任意类型的数组进行升序或降序排序。
#include <stdio.h>
#include <stdlib.h>     //qsortint compare(const void*a,const void*b)
{return ( *(int *)a - *(int *)b ); //先把void*强制转换成int*,再取指针所指空间的值
}
int main (void)
{int values[]={40,10,100,60,70,20};qsort(values,6,sizeof(int),compare);for(int i=0 ;i<6;i++)    //遍历数组printf("%d ",values[i]);return 0;
}

课后练习

1.字符指针、浮点指针以及函数指针这三种类型的变量哪个占用的内存最大?为什么?
答:指针变量也占用内存单元,而且所有类型的指针变量占用的内存大小都是相同的。也就是说,不管是指向何种对象的指针变量,它们占用的内存空间的字节数都是一样的,通常是一个机器字长。一般情况下32位系统占4个字节,64位系统占8个字节,可以用sizeof运算符测试指针变量所占字节数。

2.以下对C语言的“指针”的描述不正确的是( D )。
A.32位系统下任何类型的指针的长度都是4个字节
B.指针数据类型声明的是指针实际指向内容的数据类型
C.野指针是指向未分配或者已释放的内存地址
D.当使用free释放掉一个指针内容后,指针变量的值被置为NULL

3.有如下定义,则下列符号中均正确地代表x的地址的选项是( D )。
int x , *p;
p = &x;
A.&x、p、&x B.&、x、p C.&p、*p、x D.&x、&*p、p

4.有基本类型相同的指针p1、p2,则下列运算不合理的是( A )。
A.p1 /= 5 B.p1 - p2 C.p1 = p2 D.p1 == p2

5.以下程序的输出是( C )。
int *p = 0;
p += 6;
printf("%d\n",p)
A.12 B.72 C.24 D.0
E.6 F.任意数

6.有以下定义:
int a = 248,b = 4;
const int *d = &a;
int *const e = &b;
int const *f = &a;
则下列表达式中( BDE )是有问题的。
A.d = &b; B.*d = 8; C.*e = 34; D.e = &a;
E.f = 0x321f;

7.以下代码执行后p1+5和p2+5分别是多少?
unsigned char p1;
unsigned long p2;
p1 = (unsigned char
) 0x801000;
p2 = (unsigned long
) 0x810000;
答:
p1+5是0x801005
p2+5是0x810014

8.请问以下代码有什么问题?你会怎么改写?
char a;
char *str = &a;
strcpy(str,“hello”);
printf("%s\n",str);
答:str是一个字符变量的a地址,strcpy()函数拷贝一个串到str所指空间,类型不匹配,所以可以做如下修改:
char a;
char str100]; //用字符数组存字符串
strcpy(str,“hello”);
printf("%s\n",str);

9.以下这段程序中有什么错误?你会怎么改写?
void swap(int *p1,int *p2)
{
int *p;
*p = *p1;
*p1 = *p2;
*p2 = p;
}
答:在swap函数中p是一个野指针,并没有分配指向的空间,当执行
p = *p1时会导致程序执行崩溃。可以做如下修改:
void swap(int *p1,int *p2)
{
int *p = (int *)malloc(sizeof(int)); //动态分配一个整型空间
*p = *p1;
*p1 = *p2;
*p2 = *p;
free§; //释放空间
}

10.给出以下程序的输出结果。

#include <stdio.h>
#include <stdlib.h> int main (void)
{int *p,*q,**pp;p = (int*) malloc( 3*sizeof(int) );for(int i = 0;i < 3;i++){*(p+i) = i+1;}q = (int*) malloc( 4*sizeof(int) );for(int i = 0;i < 3;i++){*(q+i) = i+5;}pp = (int **) malloc(2*sizeof(int*));*pp++ = p;*pp = q;printf("%d,%d\n",*(*(pp+1)+1),**(--pp));free(p);free(q);free(pp);return 0;
}
    答:程序的输出结果如下:6,1
查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. es常用查询函数

    查询的时候注意必填这几个 "indexes": ["search4{app}_current_reader"], //必填, 搜索实例,如:["search4policy_current_reader"] "types": [{app}], //必填…...

    2024/4/28 4:57:36
  2. nullptr和NULL

    nullptr是c++11中的关键字,表示空指针要区分nullptr和NULL,首先要明白NULL的含义:NULL是一个宏定义,在c和c++中的定义不同,c中NULL为(void*)0,而c++中NULL为整数0//C语言中NULL定义 #define NULL (void*)0 //c语言中NULL为void类型的指针,但允许将NULL定…...

    2024/4/28 5:19:19
  3. 数据库

    创建数据库表 create table if not exists demo1( `id` int not null auto_increment, `name` varchar(20) not null default 匿名 comment 名字, `sex` varchar(2) not null default 女 comment 性别, `time` datetime default null comment 时间, primary key(`id`))engine=i…...

    2024/4/27 15:47:42
  4. Spring Cloud Gateway初体验

    SpringCloud视频教程:https://ke.qq.com/course/2805647?tuin=a3e3fb1&from_uin=171851697&from=1000201007个人博客纯净版http://www.51ufo.cn/%E5%BE%AE%E6%9C%8D%E5%8A%A1/%E5%88%86%E5%B8%83%E5%BC%8F/2020/07/11/SpringCloud%E5%85%A5%E9%97%A815-Spring-Cloud-…...

    2024/4/28 4:59:32
  5. gradle 下载的地址

    今天小G想下载一个gradle,然后找半天发现可以使用这个地址进行下载,特此标注下,以免后续使用 https://services.gradle.org/distributions/...

    2024/4/27 21:30:22
  6. 多页签excel转pdf

    安装软件 LibreOffice 1.下载地址:https://zh-cn.libreoffice.org/download/libreoffice 下载后安装 2.开始转换 文件---》打开文件 打开exel后右侧的样式里面有页面样式 ,有每一个页签(sheet)的样式,右键,修改 ,找到工作表下面的“缩放”,选择?"为打印内容的宽…...

    2024/4/28 17:41:02
  7. 投资银行业务法规汇编----仅供学习

    投资银行业务法规汇编 一、基本法规二、股票发行审核(一)首次发行 (二)股权再融资 (三)创业板 (四)科创板 (五)存托凭证 (六)优先股 (七)其他 三、债券发行审核(一)公司债 (二)可转换公司债券 (三)企业债 (四)中小企业私募债 (五)可交换公司债券 (六)…...

    2024/4/28 2:01:53
  8. 投资银行业务法规汇编----仅供学习

    投资银行业务法规汇编 一、基本法规二、股票发行审核(一)首次发行 (二)股权再融资 (三)创业板 (四)科创板 (五)存托凭证 (六)优先股 (七)其他 三、债券发行审核(一)公司债 (二)可转换公司债券 (三)企业债 (四)中小企业私募债 (五)可交换公司债券 (六)…...

    2024/4/28 3:20:12
  9. 快速迁移数据中心:华为云数据库SQL Server实践案例技术解析

    1. 简介企业或用户将数据中心部署在线下,采用独立软件提供商(Independent Software Vendor)软件进行管理。线下数据运维成本较高,故障容灾单一化,是目前遇到的瓶颈。采用云上数据库并平滑兼容线下ISV软件管理可以降低企业上云难度,加速企业上云,本文以金蝶K/3 WISE 为…...

    2024/4/28 12:42:52
  10. 老司机带你玩转面试(2):Redis 过期策略以及缓存雪崩、击穿、穿透

    前文回顾 建议前一篇文章没看过的同学先看下前面的文章: 「老司机带你玩转面试(1):缓存中间件 Redis 基础知识以及数据持久化」 过期策略 Redis 的过期策略都有哪些? 在聊这个问题之前,一定要明确的一件事情是,如非必要,任何进入缓存的数据都应该设置过期时间,因为内存…...

    2024/4/23 2:53:17
  11. ubuntu安装docker

    1使用这套脚本安装: curl -fsSL get.docker.com -o get-docker.shsudo sh get-docker.sh --mirror AzureChinaCloud2启动Docker CEsudo service docker start3测试 Docker 是否安装正确sudo service docker start4.配置Docker镜像加速器 4.1 在 /etc/docker/daemon.json 中写入…...

    2024/4/28 6:26:27
  12. 路由器端口映射失败排查方法

    许多用户设置了端口映射,但是端口映射不成功怎么办?端口映射失败最直观的判断方法就是外网电脑无法访问映射后的服务器或者主机。本文就将介绍路由器端口映射失败的排查方法,以及解决方法。失败排查排查方法一:检查访问方式可能原因:访问服务器的方式,或是访问服务器时输…...

    2024/4/28 1:12:03
  13. ArrayList类

    ArrayList - 类 用来存储数据, 可变长数组 -> 集合 所属软件包: java.util 数组长度不可变, 数组如果要扩容, 需要用到数组的复制 为了解决数组长度不可变的问题, 可以实现数组长度动态变化 int[] Student[] int[][] Room[][] ArrayList 仅支持引用类型 1.构造方法 空参构…...

    2024/4/17 4:01:36
  14. 一篇文章带你解读从初级运维工程师到资深运维专家的学习路线

    作者:JackTian 微信公众号:杰哥的IT之旅(ID:Jake_Internet)目录一、初级运维工程师1、网络技术与应用2、Linux 基础三、高级运维工程师四、资深方向总结一、初级运维工程师互联网时代,人人都离不开网络。作为一名程序员来说,最起码不需要你过多的对网络有深入的研究,对…...

    2024/4/8 6:15:09
  15. 详细解析phpstudy2016安装教程(图文)

    最新phpstudy2016安装教程及流程,帮助站长快速搭建网站服务器平台!phpstudy软件简介该程序包集成最新的Apache+Nginx+LightTPD+PHP+MySQL+phpMyAdmin+Zend Optimizer+Zend Loader,一次性安装,无须配置即可使用,是非常方便、好用的PHP调试环境。该程序绿色小巧简易迷你仅有…...

    2024/4/27 19:04:30
  16. 虚拟机的安装以及CentOS7安装

    虚拟机的安装在windows系统中安装虚拟机软件,在虚拟机软件中模拟多个操作系统虚拟机软件VMware Vmware 收费VirtualBox Oracle 免费,对主板要求高,虚拟化技术需要主板支持1、VM虚拟机安装教程1.1、虚拟机下载1.进入VMware官网,点击左侧导航栏中的下载,再点击图中标记的Wor…...

    2024/4/28 15:19:59
  17. Android手工打造脑图控件

    背景所有的开发背景都是项目需要。先上屌炸天的设计图。效果导出效果不清晰,尽量看吧。功能 脑图展示样式订制(文字颜色、图标、样式、边框..)折叠方式支持两种:a、同侧折叠不影响其他。b、同侧展开其他项折叠整体拖动待扩展... 前期思考作为一个油腻的安卓程序猿,当看到效…...

    2024/4/27 15:42:56
  18. 量化交易入门(精华必读版)

    篇文章向你介绍端到端的量化交易系统的一些基本概念。本文主要面向两类读者,第一类是正在努力寻找一份基金管理公司量化交易员工作的求职者,第二类是期望尝试开启自己“散户”算法交易事业的人士。 量化交易是数量金融学(注1)中一个极其艰深复杂的领域。若要通过面试或构造…...

    2024/4/23 1:39:49
  19. Python 定时任务的实现方式

    本文转载自:https://lz5z.com/Python%E5%AE%9A%E6%97%B6%E4%BB%BB%E5%8A%A1%E7%9A%84%E5%AE%9E%E7%8E%B0%E6%96%B9%E5%BC%8F/背景目前所在的项目组需要经常执行一些定时任务,之前都是用 Node.JS 的 cron来实现 schedule job。可是这次需要连接不同的 DB,而且实现的逻辑也有些…...

    2024/4/28 3:57:22
  20. ubuntu安装tensorflow

    全文转自:https://zhuanlan.zhihu.com/p/504499000. 我们开始吧先更新一下系统:sudo apt-get update sudo apt-get upgrade1. 安装显卡驱动如果你用的是 Ubuntu 桌面版(即带图形化界面),那么去 Nvidia 官网下载驱动就是你遇到的第一个陷阱。当你试图安装时,系统会报错说你…...

    2024/4/24 14:45:18

最新文章

  1. ios微信小程序禁用下拉上拉

    第一步&#xff1a; page.json配置页面的"navigationStyle":"custom"属性&#xff0c;禁止页面滑动 "navigationStyle":"custom" 第二步&#xff1a; 页面里面使用scroll-view包裹内容&#xff0c;内容可以内部滑动 <view class&…...

    2024/4/28 20:52:01
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/3/20 10:50:27
  3. Gin环境搭建详解

    Gin环境搭建详解&#xff1a; 要安装Gin软件包&#xff0c;需要先安装Go并设置Go工作区。Gin环境搭建步骤如下&#xff1a; 【Gin框架】Gin环境搭建 Gin程序的热加载 Gin路由 GET POST PUT DELETE 1. 下载并安装 gin &#xff1a; $ go get -u github.com/gin-gonic/gin 2. …...

    2024/4/19 7:20:56
  4. PHP+python高校教务处工作管理系统q535p

    开发语言&#xff1a;php 后端框架&#xff1a;Thinkphp/Laravel 前端框架&#xff1a;vue.js 服务器&#xff1a;apache 数据库&#xff1a;mysql 运行环境:phpstudy/wamp/xammp等 系统根据现有的管理模块进行开发和扩展&#xff0c;采用面向对象的开发的思想和结构化的开发方…...

    2024/4/26 8:31:01
  5. 一个浮动绝对居中的tailwindcss

    今天改进图片组件&#xff0c;遇到个SVG绝对居中的问题。想起之前大概是通过top left来实现&#xff0c;由于组件的宽高需要动态输入。不能定死宽高&#xff0c;于是想起来问GPT。刚开始老是给一些很菜的代码&#xff0c;不是我想要的 气不打一处来&#xff0c;索性给他限死框框…...

    2024/4/26 21:09:53
  6. 416. 分割等和子集问题(动态规划)

    题目 题解 class Solution:def canPartition(self, nums: List[int]) -> bool:# badcaseif not nums:return True# 不能被2整除if sum(nums) % 2 ! 0:return False# 状态定义&#xff1a;dp[i][j]表示当背包容量为j&#xff0c;用前i个物品是否正好可以将背包填满&#xff…...

    2024/4/28 4:04:40
  7. 【Java】ExcelWriter自适应宽度工具类(支持中文)

    工具类 import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet;/*** Excel工具类** author xiaoming* date 2023/11/17 10:40*/ public class ExcelUti…...

    2024/4/28 12:01:04
  8. Spring cloud负载均衡@LoadBalanced LoadBalancerClient

    LoadBalance vs Ribbon 由于Spring cloud2020之后移除了Ribbon&#xff0c;直接使用Spring Cloud LoadBalancer作为客户端负载均衡组件&#xff0c;我们讨论Spring负载均衡以Spring Cloud2020之后版本为主&#xff0c;学习Spring Cloud LoadBalance&#xff0c;暂不讨论Ribbon…...

    2024/4/28 16:34:55
  9. TSINGSEE青犀AI智能分析+视频监控工业园区周界安全防范方案

    一、背景需求分析 在工业产业园、化工园或生产制造园区中&#xff0c;周界防范意义重大&#xff0c;对园区的安全起到重要的作用。常规的安防方式是采用人员巡查&#xff0c;人力投入成本大而且效率低。周界一旦被破坏或入侵&#xff0c;会影响园区人员和资产安全&#xff0c;…...

    2024/4/28 18:31:47
  10. VB.net WebBrowser网页元素抓取分析方法

    在用WebBrowser编程实现网页操作自动化时&#xff0c;常要分析网页Html&#xff0c;例如网页在加载数据时&#xff0c;常会显示“系统处理中&#xff0c;请稍候..”&#xff0c;我们需要在数据加载完成后才能继续下一步操作&#xff0c;如何抓取这个信息的网页html元素变化&…...

    2024/4/28 12:01:03
  11. 【Objective-C】Objective-C汇总

    方法定义 参考&#xff1a;https://www.yiibai.com/objective_c/objective_c_functions.html Objective-C编程语言中方法定义的一般形式如下 - (return_type) method_name:( argumentType1 )argumentName1 joiningArgument2:( argumentType2 )argumentName2 ... joiningArgu…...

    2024/4/28 12:01:03
  12. 【洛谷算法题】P5713-洛谷团队系统【入门2分支结构】

    &#x1f468;‍&#x1f4bb;博客主页&#xff1a;花无缺 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 花无缺 原创 收录于专栏 【洛谷算法题】 文章目录 【洛谷算法题】P5713-洛谷团队系统【入门2分支结构】&#x1f30f;题目描述&#x1f30f;输入格…...

    2024/4/28 12:01:03
  13. 【ES6.0】- 扩展运算符(...)

    【ES6.0】- 扩展运算符... 文章目录 【ES6.0】- 扩展运算符...一、概述二、拷贝数组对象三、合并操作四、参数传递五、数组去重六、字符串转字符数组七、NodeList转数组八、解构变量九、打印日志十、总结 一、概述 **扩展运算符(...)**允许一个表达式在期望多个参数&#xff0…...

    2024/4/28 16:07:14
  14. 摩根看好的前智能硬件头部品牌双11交易数据极度异常!——是模式创新还是饮鸩止渴?

    文 | 螳螂观察 作者 | 李燃 双11狂欢已落下帷幕&#xff0c;各大品牌纷纷晒出优异的成绩单&#xff0c;摩根士丹利投资的智能硬件头部品牌凯迪仕也不例外。然而有爆料称&#xff0c;在自媒体平台发布霸榜各大榜单喜讯的凯迪仕智能锁&#xff0c;多个平台数据都表现出极度异常…...

    2024/4/27 21:08:20
  15. Go语言常用命令详解(二)

    文章目录 前言常用命令go bug示例参数说明 go doc示例参数说明 go env示例 go fix示例 go fmt示例 go generate示例 总结写在最后 前言 接着上一篇继续介绍Go语言的常用命令 常用命令 以下是一些常用的Go命令&#xff0c;这些命令可以帮助您在Go开发中进行编译、测试、运行和…...

    2024/4/28 9:00:42
  16. 用欧拉路径判断图同构推出reverse合法性:1116T4

    http://cplusoj.com/d/senior/p/SS231116D 假设我们要把 a a a 变成 b b b&#xff0c;我们在 a i a_i ai​ 和 a i 1 a_{i1} ai1​ 之间连边&#xff0c; b b b 同理&#xff0c;则 a a a 能变成 b b b 的充要条件是两图 A , B A,B A,B 同构。 必要性显然&#xff0…...

    2024/4/27 18:40:35
  17. 【NGINX--1】基础知识

    1、在 Debian/Ubuntu 上安装 NGINX 在 Debian 或 Ubuntu 机器上安装 NGINX 开源版。 更新已配置源的软件包信息&#xff0c;并安装一些有助于配置官方 NGINX 软件包仓库的软件包&#xff1a; apt-get update apt install -y curl gnupg2 ca-certificates lsb-release debian-…...

    2024/4/28 4:14:21
  18. Hive默认分割符、存储格式与数据压缩

    目录 1、Hive默认分割符2、Hive存储格式3、Hive数据压缩 1、Hive默认分割符 Hive创建表时指定的行受限&#xff08;ROW FORMAT&#xff09;配置标准HQL为&#xff1a; ... ROW FORMAT DELIMITED FIELDS TERMINATED BY \u0001 COLLECTION ITEMS TERMINATED BY , MAP KEYS TERMI…...

    2024/4/27 13:52:15
  19. 【论文阅读】MAG:一种用于航天器遥测数据中有效异常检测的新方法

    文章目录 摘要1 引言2 问题描述3 拟议框架4 所提出方法的细节A.数据预处理B.变量相关分析C.MAG模型D.异常分数 5 实验A.数据集和性能指标B.实验设置与平台C.结果和比较 6 结论 摘要 异常检测是保证航天器稳定性的关键。在航天器运行过程中&#xff0c;传感器和控制器产生大量周…...

    2024/4/27 13:38:13
  20. --max-old-space-size=8192报错

    vue项目运行时&#xff0c;如果经常运行慢&#xff0c;崩溃停止服务&#xff0c;报如下错误 FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory 因为在 Node 中&#xff0c;通过JavaScript使用内存时只能使用部分内存&#xff08;64位系统&…...

    2024/4/28 12:00:58
  21. 基于深度学习的恶意软件检测

    恶意软件是指恶意软件犯罪者用来感染个人计算机或整个组织的网络的软件。 它利用目标系统漏洞&#xff0c;例如可以被劫持的合法软件&#xff08;例如浏览器或 Web 应用程序插件&#xff09;中的错误。 恶意软件渗透可能会造成灾难性的后果&#xff0c;包括数据被盗、勒索或网…...

    2024/4/28 12:00:58
  22. JS原型对象prototype

    让我简单的为大家介绍一下原型对象prototype吧&#xff01; 使用原型实现方法共享 1.构造函数通过原型分配的函数是所有对象所 共享的。 2.JavaScript 规定&#xff0c;每一个构造函数都有一个 prototype 属性&#xff0c;指向另一个对象&#xff0c;所以我们也称为原型对象…...

    2024/4/27 22:51:49
  23. C++中只能有一个实例的单例类

    C中只能有一个实例的单例类 前面讨论的 President 类很不错&#xff0c;但存在一个缺陷&#xff1a;无法禁止通过实例化多个对象来创建多名总统&#xff1a; President One, Two, Three; 由于复制构造函数是私有的&#xff0c;其中每个对象都是不可复制的&#xff0c;但您的目…...

    2024/4/28 7:31:46
  24. python django 小程序图书借阅源码

    开发工具&#xff1a; PyCharm&#xff0c;mysql5.7&#xff0c;微信开发者工具 技术说明&#xff1a; python django html 小程序 功能介绍&#xff1a; 用户端&#xff1a; 登录注册&#xff08;含授权登录&#xff09; 首页显示搜索图书&#xff0c;轮播图&#xff0…...

    2024/4/28 8:32:05
  25. 电子学会C/C++编程等级考试2022年03月(一级)真题解析

    C/C++等级考试(1~8级)全部真题・点这里 第1题:双精度浮点数的输入输出 输入一个双精度浮点数,保留8位小数,输出这个浮点数。 时间限制:1000 内存限制:65536输入 只有一行,一个双精度浮点数。输出 一行,保留8位小数的浮点数。样例输入 3.1415926535798932样例输出 3.1…...

    2024/4/27 20:28:35
  26. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  27. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  28. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  29. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  30. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  31. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  32. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  33. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  34. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  35. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  36. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  37. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  38. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  39. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  40. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  41. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  42. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  43. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  44. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  45. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57