基础知识
stdio= standard Input output , h= head
stdio.h =一个包含了输入输出的头文件,
#include
#include
#include
四种基本数据类型
(一)int-32bit longlong-64bit
*如果long long型赋大于2^31-1的初值,则需要在后面加LL
如 long long bignum=123456798012345LL;
(二)float-32bit (有效精度只有6-7位) double-64bit(有效精度15-16位)
*碰到浮点型数据都用double来储存
int main()
{
char c1='z',c2='j',c3=117;
printf("%c%c%c",c1,c2,c3);
printf("\n%c%c%d,c1,c2,c3);
return 0;
}
输出结果:
zju
zj117
(三)char
char c; *字符变量,c可以被赋值
char c=’e’; *’e’字符常量,单引号标注,可以被赋值给字符变量;
*字符串常量,用双引号标记的字符集,不能赋值给字符变量;
*转义字符:\n换行 \0空字符null
(四)BOOL
*整型常量在赋值给布尔型变量时会自动转换为true/false。如-1会转换成1;
强制类型转换
形式:(新类型名)变量
观察例子里面强制类型转换并不是四舍五入,而是直接去掉尾数。
被除数和除数都是整型时,也是直接去掉尾数。
int main()
{
double r = 12.56;
printf("%d", (int)r);
return 0;
}
输出结果:
12
int main()
{
int a = 3, b = 5;
printf("%.2f", a / b);
printf("\n%.2f", (double)a / (double)b);
return 0;
}
输出结果:
0.00
0.60
符号常量和const常量
*符号常量=宏定义=宏替换,末尾不加分号 格式:#define 标识符 常量
*const常量,末尾加分号 格式: const 数据类型 变量名=常量;
符号常量× const常量√
条件运算符
条件运算符是C语言中唯一的三目运算符,格式为(A?B:C)
即若A为真,执行B并返回结果,否则执行C并返回结果。
位运算符
算数优先级: 位运算符<算数运算符
a<
a|b a与b按位或
a^b a与b按位异或
~a a按位取反
使用scanf / printf 输入/输出
cin / cout × scanf / printf √
同一个程序中使用cout和printf ×
scanf(“格式控制”,变量地址);
pringf(“格式控制”,变量名称);
longlong %lld scanf(“%lld”,&n);
double %lf scanf(“%lf”,&db); %f printf("%f",db);*注意double特殊性
char %c scanf(“%c”,&c); *并不以什么(空格或换行)为结束标志
字符串string %s scanf(“%s”,str); *注意字符串无取值符并且以换行为结束标志
*除了char / string,scanf都以空格为结束标志
*如果想要输出’%’’’,需要在前面再加一个%或\,如
printf("%%");
printf("\\");
*有几种比较常用的输出格式:
%md: 不足m位以m位进行右对齐输出,空格补齐;超过m位保持原样;
%0md: 同上,但用0补齐;
%.mf:浮点数“四舍六入五成双”规则保留m位小数,“四舍五入”为round函数。
int main()
{
int a;
double b;
char c;
scanf("%d,%lf,%c", &a, &b, &c);
printf("a=%d,b=%lf,c=%c", a, b, c);
return 0;
}
错误:C4996 ‘scanf’: This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
查找资料 :
这里是引用
ANSI C中没有scanf_s(),只有scanf(),scanf()在读取时不检查边界,所以可能会造成内存泄露。所以VS中提供了scanf_s()
在最新的VS2017中也提供了scanf_s()在调用时,必须提供一个数字以表明最多读取多少位字符。
如果想继续使用scanf这个不安全的函数可以使用宏命令来阻止错误的产生
#define _CRT_SECURE_NO_DEPRECATE
请把宏命令放在最前面
或者编译选项中加/D_CRT_SECURE_NO_DEPRECATE
或者在所有.c/.cpp文件前面添加#pragma warning(disable:4996)
scanf()函数是标准C中提供的标准输入函数,用以用户输入数据
scanf_s()函数是Microsoft公司VS开发工具提供的一个功能相同的安全标准输入函数,VS系统提供了scanf_s()。在调用该函数时,必须提供一个数字以表明最多读取多少位字符。
scanf()在读取数据时不检查边界,所以可能会造成内存访问越界:
//例如:分配了5字节的空间但是用户输入了10字节,就会导致scanf()读到10个字节
char buf[5]={’\0’};
scanf("%s", buf);
//如果输入1234567890,则5以后的部分会被写到别的变量所在的空间上去,从而可能会导致程序运行异常。
以上代码如果用scanf_s()则可避免此问题:
char buf[5]={’\0’};
scanf_s("%s",buf,5); //最多读取4个字符,因为buf[4]要放’\0’
//如果输入1234567890,则buf只会接受前4个字符
注: scanf_s最后一个参数n是接收缓冲区的大小(即buf的容量),表示最多读取n-1个字符.
PS: 很多带“_s”后缀的函数是为了让原版函数更安全,传入一个和参数有关的大小值,避免引用到不存在的元素,防止hacker利用原版的不安全性(漏洞)黑掉系统。
版权声明:本文为CSDN博主「子沐」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_41953685/article/details/80708100
以上查找资料部分为转载,通过上面的知识,使用了如下的解决办法:
1、将scanf函数直接改成scanf_s函数,问题解决;(最推荐)
2、在文件顶部加入宏命令:#define _CRT_SECURE_NO_WARNINGS
3、或者编译选项中加/D_CRT_SECURE_NO_DEPRECATE(这个方法还不会。。)
4、更改”属性"-“c/c++”-"SDL 检查"选择“否”即可。(推荐)
解决完这个问题后,发现也可以解决同时遇到的另一个问题了
int main()
{
int a;
char c, str[10];
scanf("%d%c%s", &a, &c,str);
printf("a=%d,c=%c,str=%s", a, c, str);
return 0;
}
在未解决上述问题时,程序出错退出。
采用方法4可以很快速地解决问题,但这个方法显然不够优雅,下面思考如何采用方法1,也就是使用scanf_s函数解决这个问题
首先来开看MSDN上对scanf_s的一段代码示例节选
int i, result;
float fp; char c, s[81];
wchar_t wc, ws[81];
result = scanf_s( “%d %f %c %C %s %S”, &i, &fp, &c, 1, &wc, 1, s, 81, ws, 81 );
要注意,对于%d和%f是不用设置传入参数大小值的
对于《算法笔记》中的例子,使用scanf_s函数时,注意对str[10]的数组,
当输入为 “1 abcdeabcde” 时
设置长度若为11
int main()
{
int a;
char c, str[10];
scanf_s("%d%c%s", &a, &c,1,str,11);
printf("a=%d,c=%c,str=%s", a, c,str);
return 0;
}
程序出现错误,其实这个错误很蠢,数组只有10位,怎么能写11呢,重要的是下面一个实验
scanf_s("%d%c%s", &a, &c,1,str,10);
buf改成10,当输入仍为“1 abcdeabcde”的时候,str的输出出错
因为其实str中只能放9位字符,这里边界检查出错
如果将输入改成“1 abcdeabcd”则输出符合期待为
getchar / putchar 输入/输出字符
int main()
{
char a, b, c;
a = getchar();
getchar();
b = getchar();
c = getchar();
putchar(a);
putchar(b);
putchar(c);
}
输入“abc"将会输出
a
c
因为getchar可以识别换行符。
typedef
typedef能给一个复杂的数据类型起一个别名,如
typedef long long LL;//给long long起别名为LL
常用math函数
*fabs(double x) 取绝对值;
*floor(double x) / cell(double x) 向下取整/向上取整,返回double!型;
*pow(double r,double p) 返回r的p次方;
*sqrt(double x) 返回double型变量的算数平方根;
*asin(double x)/acos(double x)/atan(double x)
注意以上参数都是double型!
有一个很有意思的规定scanf_s/scanf只有在读入< Enter>时才能换行的办法:
scanf("%[^\n]", str, 50);
练习:
例题1-1-1:按要求输出信息(1)
编写一个C程序,要求在屏幕上输出一下一行信息。
This is my first c program!
输入
无
输出
This is my first c program!
#include
#include
int main()
{
printf("This is my first c program!");
return 0;
}
例题1-1-2 按要求输出信息(2)
题目描述
编写一个C语言程序,输出以下信息:
********************.
Very Good!
********************.
输入
无
输出
********************.
Very Good!
********************.
#include
#include
int main()
{
printf("********************\nVery Good!\n********************");
return 0;
}
例题1-2-1 求两个整数之和(1)
题目描述
设置3个变量a, b, sum,其中a, b用来存放两个整数,sum用来存放a, b两个数的和,通过赋值(即采用赋值运算符"=")的方式将a初始化为123,b初始化为456,并把两个变量相加的结果赋值给sum。
输入
无,变量在程序中以赋值的方式给定初值。
输出
sum = 结果
#include
#include
int main()
{
int a=123, b=456, sum;
sum = a + b;
printf("sum=%d", sum);
return 0;
}
例题1-2-2 求两整数数之和(2)
题目描述
从键盘上输入两个整数,并输出这两个数的和,即你的任务是计算a + b。
输入
输入空格分隔的两个整数
输出
对于用空格分隔的两个整数,求其和。
#include
int main()
{
int a, b, sum;
scanf("%d %d", &a, &b);
sum = a + b;
printf("%d", sum);
return 0;
}
例题3-5 求一元二次方程的根
题目描述
求一元二次方程ax2 + bx + c = 0的根,三个系数a, b, c由键盘输入,且a不能为0,且保证b2 - 4ac>0。
程序中所涉及的变量均为double类型。
输入
以空格分隔的一元二次方程的三个系数,双精度double类型
输出
分行输出两个根如下(注意末尾的换行):
r1 = 第一个根
r2 = 第二个根
结果输出时,宽度占7位,其中小数部分2位。
#include
#include
int main()
{
double a, b, c, p;
scanf("%lf %lf %lf", &a, &b, &c);
p = b*b - 4*a*c;
if (a != 0 &&p >= 0)
{
printf("r1=%7.2f\nr2=%7.2f", (-b + sqrt(p)) / (2 * a), (-b - sqrt(p)) / (2 * a));
}
return 0;
}
例题3-9 字符输入输出
题目描述
从键盘输入三个字符BOY,然后把他们输出到屏幕上
输入
BOY三个字符,中间无分隔符
输出
BOY,注意末尾的换行
#include
#include
int main()
{
char str[5];
scanf("%s",str);
printf("%s", str);
return 0;
}