在接下来的一段时间内,我会陆续更新《算法笔记》这本书的算法内容,写在这一是为了分享,二是为了自身的复习与查看。这次的是c/c++一些简要问题的补充,并不是详细的阐述C++的用法,若想要系统的学习C++,建议参考那些专门讲解C/C++的书,或者参考这里:C菜鸟教程 、C++菜鸟教程。
变量类型
整型
整型可分为短整型short
、整型int
(也被称为long int
)、长整型long long
(也被称为long long int
)。
整型 | 取值范围 |
---|---|
int | -231 ~ +(231 - 1) |
long long | -263 ~ +(263 - 1) |
注
:如果long long 型赋予大于231 - 1的初值,则需要在初值后面加上LL,否则编译会报错。
print("%d",a); //int类型输出格式
print("%lld",c); //long long类型输出格式
浮点型
单精度 float
有效精度只有6~7位。一个浮点数占用32bit,其中1bit作为符号位,8bit作为指数位,23bit作为尾数位;
双精度 double
有效精度有15~16位。一个浮点数占用64bit,其中1bit作为符号位,11bit作为指数位,52bit作为尾数位。
print("%f",c); //float和double类型输出格式
字符型
- 09、AZ、az在ASCII码的中编号为4857、6590、97122,其中小写字母比大写字母的ASSII码值大32。
- 在C语言中,字符常量必须用单引号标注。
- 转义字符
\n //表示换行
\0 //表示空字符NULL,其ASCII码为0,请注意\0不是空格
\t //Tab键
-
字符串常量
在c中没有一种单独的一种基本数据类型来存储字符串,只能使用字符数组的形式,字符串常量用双引号标注。
char a[11] = "qwertyuiop";
printf("%s",a);
布尔型
布尔型在C++中可直接使用,但在C语言中必须添加stdbool.h
头文件。
整型常量在赋值的给布尔型变量时会自动转换为true
或者false
。其中,“非零”时包括正整数和负整数的,他们都会转化为true
;只有“零”转化为fasle
,非零即一。
强制类型转换
强制类型转换格式如下:
//格式:(新类型名)变量名
long long s = 23;
int a = -23;
printf("%d %d",(bool)s,(bool)a); //输出结果为: 1 1
符号常量和const常量
符号常量通俗的讲就是“替换”,即用一个标识符来替代常量,又称为“宏定义”或“宏替换”。
#define 标识符 常量 //末尾不加分号
另一种方法是使用const
,格式如下:
const 数据类型 变量名 = 常量 //常量一旦确定其值之后就无法改变
上面两种方法定义常量都可以,但是推荐const写法。
补充
define除了可以定义常量外,其实可以定义任何语句或字段。
#define 标识符 任何语句或片段
#define ADD(a, b) ((a)+(b)) //下面就可以用ADD(a, b)了,相当于输入了((a)+(b))
运算符
其他的运算符就不说了,说一下自增自减运算符
a++ a-- //先使用再加(减)一
++a --a //先加(减)一再使用
条件运算符:C语言中唯一的三目运算符
A ? B : C ; //A判定正确的话执行B指令,否则执行C指令。
scanf 输入函数
格式如下:
scanf("格式控制", 变量地址); //格式
scanf("%d:%d",&n); //输入时的输入举例: 8:20 (即输入必须和scanf中相同)
下面解释一下&n
前面的&
。在C语言中,变量在定义之后,就会在计算机内存中分配一块空间给这个变量,该空间在内存中的地址称为变量的地址。为了得到变量的地址,需要在变量前面家一个&(取地址运算符)。
注意:
- 数组名称本身就代表了这个数组第一个元素的地址,不需要再加地址运算符;除了char数组整个输入的情况下不再
&
之外,其他变量类型都需要加&。 - 除了%c外,scanf 对其他格式符的输入是以空白符(空格,Tab键)为结束判断标志的,也就是说,%c是可以读入空格和换行的。
- %s 字符数组是以空格跟换行作为读入结束标志的,即如果你在输入一串字符串时中间有空格,那么这个字符串从空格那个地方就断掉了。
printf 输出函数
正规的就不说了,下面说一下几个**实用的输出格式。
%md
%md可以使不足m位的int
型变量以m位进行右对齐输出,其中高位用空格补齐;如果变量本身超过m位,则保持原样。
% 0md
%0md只是在%md中间多加了一个0,和%md的唯一不同点在于,当变量不足m位时,将在前面补足够数量的0而不是空格。
%.mf
%.mf 可以让浮点数保留m位小数输出,使用的精度为“四舍六入五成双”规则,如果是四舍五入,则使用round
函数。
代码演示
#include <stdio.h>
int main()
{
int a = 123;
int b = 123456;
double c = 12.3456;
printf("%5d\n%5d\n%.2f\n",a,b,c);
printf("%05d\n%05d\n%.3f\n",a,b,c);
return 0;
}
运行结果:
123
123456
12.35
00123
123456
12.346
getchar / putchar
getchar() 用来输入单个字符,putchar()用来输出单个字符,getchar()可以识别换行符,所以输入的时候不要随便点击enter
键。
#include <stdio.h> //这里给出用法,具体结果自己跑吧。
int main()
{
switch(getchar()){ //接收字符
case 'a':
printf("+++++++\n");
break;
default:
printf("-------\n");
}
char a ='a';
putchar(a); //输出字符
return 0;
}
常用math函数
如果要使用,需要在程序开头加上 math.h 头文件。
fabs(double x)
该函数用于对 double 型变量取绝对值。
floor(double x)与ceil(double x)
这两个函数分别用于double型变量的向下取整和向上取整,返回类型为double类型。
pow(double x,double y)
该函数用于返回xy,要求 x 和 y 都是 double 类型。
sqrt(double x)
该函数用于返回double 型变量的算术平方根。
log(double x)
该函数用于返回double 型变量的以自然对数为底的对数,另外,若想求对任意底数的函数,应使用换底公式。
三角函数公式
- sin(double x) 正弦
- cos(double x)
- tan(double x)
- asin(double x) 反正弦
- acos(double x)
- atan(double x)
round(double x)
该函数用于将 double 型变量x四舍五入,返回类型也是 double型,需要用强制类型转换进行取整操作。
冒泡排序
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
//冒泡排序 6个数
int a[10]={2,4,9,7,3,5};
int i,j;
for(i=1;i<6;i++){ //n-1轮
for(j=0;j<6-i;j++){ //第i轮时前n-i对相比较
if(a[j]>a[j+1]){
int temp;
temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
for(i=0;i<6;i++){
printf("%d",a[i]);
}
return 0;
}
数组
本来不想说了,这里插两句,就是C语言的数组输出必须用循环,没有一次性输出的函数。
另外,如果数组大小过大(大概106级别),则需要将其定义在主函数外面,否则会使程序异常退出,原因是函数内部申请的局部变量来自系统栈,允许申请的空间较小;而函数外部申请的局部变量来自静态存储区,允许申请的空间较大。
memset赋值函数
使用前请添加头文件:string.h
memset(数组名,值,sizeof(数组名)); //对数组中每一个元素赋相同的值
注意:memset是按字节赋值,即对每个字节赋相同的值,这点要重点注意,请利用二进制知识进行运用。举例来说,int占用4个字节,所以该函数第二个 值 = 1
,结果一定不是1,而是00000001 00000001 00000001 00000001
。
字符数组
这里重点谈一下字符数组的几种输入输出方式,并比较一下异同。
scanf()与printf()
scanf()对字符类型有%c和%s两种格式。其中%c对应单个字符,可以存储空格和换行并将其输出;而%s对应字符串,不可以存储空格和换行,而是通过空格和换行来作为一个字符串的结束。
#include <stdio.h>
#include <string.h>
int main()
{
char a;
scanf("%c",&a);
printf("----------");
printf("%c",a);
printf("----------");
return 0;
}
输入回车效果如下:getchar()与putchar()
上面已经说过这里就不说了。
gets()与puts()
gets()用于输入一行字符串,并将其存放于一维数组(或二维数组的一维)中;puts()用于将一维数组(或二维数组的一维)在界面上输出,并紧跟一个换行。
注: gets识别换行符\n
作为输入结束,因此 scanf 完一个字符串后,如果要使用 gets ,需使用 getchar 接收字符串的换行符。怎么理解呢,拿下面的代码跑一下就清楚了。
#include <stdio.h>
int main()
{
char str_1[100];
char str_2[100];
scanf("%s",str_1);
getchar(); //等跑完在注释掉此行试试代码效果就清楚了。
gets(str_2);
puts(str_1);
printf("--------\n");
puts(str_2);
return 0;
}
友情提醒
- 结束符
\0
的ASCII码为0,即空字符NULL,占用一个字符位,因此开字符数组的时候千万要记得字符数组的长度一定要比实际存储字符串的长度多1。 - int 型数组的末尾不需要加\0,仅char 型数组需要。
- 如果不是使用 scanf 函数的%s 格式或 gets 函数输入字符串,请一定要在输入的每个字符串末尾加入
\0
。
#include <stdio.h>
int main()
{
char str[15];
int i;
for(i=0;i<3;i++){
str[i] = getchar();
}
str[3] = '\0'; //!!!重点!!!一定要添加
puts(str);
return 0;
}
string.h
该头文件包含了许多用于字符数组的函数,下面将做一些简要介绍。
strlen()
strlen函数可以得到字符数组中第一个\0
前的字符的个数,其格式如下:
strlen(str); //其中 str 为字符数组
strcmp()
该函数可以返回两个字符串大小的比较结果,比较原则是按照字典序,格式如下:
strcmp(str1,str2); //其中str1、str2都是字符数组
strcpy()
strcpy函数可以把一个字符串复制给另一个字符串,格式如下:
strcpy(str1,str2); //其中str1、str2都是字符数组
strcat()
strcat 函数可以把一个字符串接到另一个字符串后面,其格式如下:
strcat(str1,str2); //其中str1、str2都是字符数组 str1 = str1 + str2