一、数据类型
1.常量
2.float浮点表示
3.字符型
4.char(大小写)
#include <stdio.h>
//根据数字输出字符--int值可以直接输出为char
int main() {
int value;
while (1){
scanf("%d",&value);
if(value<65||value>122){
printf("The value you entered is invalid!\n");
continue;
}
printf("%c\n",value);
break;
}
return 0;
}
5.字符串常量的结束标志占字节大小
二、混合运算 printf
%0.2f --0表示不限制字符数 仅保留俩位小数
四、进制转化
如今在计算机中都是以16进制数进行存储 高位在后 低位在前所以123 表现为7b 000....
debug进行取 &ten
五、 scanf函数
scanf原理 :标准缓冲区
混合接收
总之: scanf 接收是标准缓冲区
且接收
浮点型变量 整型变量 字符串 因为他会忽略\n(回车) 空格等字符 所以 不管缓冲区有没有\n 都不影响f的赋值而在接收%c 字符型变量时
要考虑 标准缓冲区中是否有 \n 空格等字符 因为它不会忽略
六、算术运算符与算术表达式
关系运算符的优先级小于算术运算符
关系运算符不连用 搭配逻辑运算符使用
3<a<10 错误 ---因为 这个a 表示就是比3大 比10小 或的关系 所以表示全集R
正确写法:a>3 && a<10 这个才表示比3大并且比10小
#include <stdio.h>
int main() {
int a;
while(scanf("%d",&a)){
if(3<a<10){
printf("1111");
} else{
printf("2222");
}
}
printf("Hello, World!\n");
return 0;
}
七、逻辑运算符
闰年: 能被4整除但是不能被100整除 或者 可以被400整除
短路运算:
#include <stdio.h>
//短路运算-逻辑与 逻辑或
int main() {
int a=0;
//逻辑与
a&&printf("you can not see me!\n");
int b=1;
//逻辑或
b|| printf("you can not see me!\n");
return 0;
}
八、赋值运算符
左值:变量
右值:表达式
九、求字节运算符
sizeof()--求常量 与变量 所占字节大小
十、OJ判题系统-循环运行时异常、char接收异常:
#include <stdio.h>
//判断某个年份是不是闰年--这个死循环必须 有停止条件不然OJ会报运行时异常
int main() {
int year;
while (1) {
scanf("%d", &year);
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
printf("yes\n");
break;
} else {
printf("no\n");
break;
}
}
return 0;
}
用char来接收这个输入的数字 -这样是不可以的
因为 char是1个字节的 而int是4个字节的
#include <stdio.h>
//输入数字 输出对应的字符--用int来接收输入的数字才是可以的
int main() {
int year;
scanf("%d",year);
printf("%c\n",year);
return 0;
}
OJ题读取策略:
第一种情况:读取一行,写一个scanf即可;
第二种情况:读取多行,例如3行 for循环读取3次即可;
十一、逆序数、反置数、对称数--用简单的34换为43
获取反置数:
while (i){ number=number*10+i%10; i=i/10; }
#include <stdio.h>
//输入一个整型数,判断是否是对称数,如果是,输出yes,否则输出no,不用考虑这个整型数过大,int类型存不下,不用考虑负值;
//例如 12321是对称数,输出yes,124421是对称数,输出yes,1231不是对称数,输出no
int main() {
int i,number,old;
scanf("%d",&i);
//12321
old=i;
//核心
while (1){
number=number*10+i%10;
i=i/10;
if(i==0){
break;
}
}
//核心
printf("%d\n",number);
if(number==old){
printf("yes\n");
} else{
printf("no\n");
}
return 0;
}
十二、换钱
#include <stdio.h>
//某人想将手中的一张面值100元的人民币换成10元、5元、2元和1元面值的票子。要求换正好40张,且每种票子至少一张。问:有几种换法?这是我写的代码 请问哪里不对
int main() {
int count=100,sum=0;
for (int i = 1; i <=40 ; i++) {
for (int j = 1; j <=40 ; ++j) {
for (int k = 1; k <= 40; ++k) {
for (int l = 1; l <=40 ; ++l) {
//注意判断的限制条件有俩个
if(i*10+5*j+2*k+l==count&&i+j+k+l==40){
sum++;
printf("10=%d 5=%d 2=%d 1=%d\n",i,j,k,l);
}
}
}
}
}
printf("%d\n",sum);
return 0;
}
十三、一维数组
注意:
数组不能传递长度
因为它传递给函数的是起始地址
数组越界--(覆盖其他变量)
字符数组初始化:
char c[6]=“hello”; 因为最后有个结束符\n 用%c来输出
字符串的接收:
char c[100];
scanf("%s",c);//会自动往字符串中放入结束符 因为c本身就含有起始地址所以可以省略&
如果 c[100]="123"; 那么 接收的时候 会把012三个位置进行覆盖了
%s 会忽略空格
Win下 使用VS集成开发环境不能使用gets:
char c[100];
gets等价于fgets(c,sizeof(c),stdin);
str:
# include <string.h>
char c[100], d[50];
strlen(c);//获取长度
strcat(c,d);//拼接d到c
strcpy(c,d);//把d复制到c
strcmp(c,d);//比较字符串大小 c>d 正值 c=d 0 c<d 负值
十四、数组OJ
#include <stdio.h>
//输入N个数(N小于等于100),输出数字2的出现次数;
int main() {
int a[100];
int count=0,len;
scanf("%d",&len);
for (int i = 0; i < len; ++i) {
scanf("%d",&a[i]);
if(a[i]==2){
count++;
}
}
printf("%d\n",count);
return 0;
}
十五、指针
注意:
32位中 指针占4个字节 其他占8个字节
指针的初始化 (某个相同类型的变量取地址) int i; int *p=&i; *-取值
1.指针传递
值传递:形参的改变不会影响实参
change(int j) change(i)
值传递中的地址传递:
change(int *j) change(&i)
2.指针偏移(指针的加减)
*(p+1) --本质上偏移的是 同类型的sizeof(int) 即四个字节---指针遍历数组
因此 --接收数组的值其实就是地址
char c[100]; change(char *d);-- *d 不管什么 因为传过来是指针那么sizeof(d) 一定是8个字节
因为是指针
3.动态内存申请
#include <stdio.h>
#include <stdlib.h> //malloc所需头文件
#include <string.h> //string所需头文件
//内存空间申请
int main() {
int size=10;
char *p,*q;//要申请的是一片存储char的内存空间
//void* 无类型指针--- malloc返回
//无类型指针不可进行偏移 因此申请下这片堆内存中的空间后 我们需要把他强转为我们需要的指针来存储这片空间起始地址
p=(char*)malloc(size);//申请10
strcpy(p,"hello");
puts(p);
//还给操作系统申请的空间
free(p);//这里p不可进行偏移 如果要进行偏移我们可以定义一个 *q指针来代替 不可以free(p+1);
return 0;
}
4.堆和栈的差异
#include <stdio.h>
#include <stdlib.h>
//函数栈 在函数结束后 的内存空间被收回了
//因此返回的a的内存空间 主函数是接收不到的
char* return_stack(){
char a[100]="hello stack";
puts(a);
return a;
}
//函数栈 向内存堆申请空间
// 在函数结束后 只是函数栈被收回了
// 但是 堆申请的空间还在因此主函数可以接收到申请的内存空间地址 并且可以得到空间中的值
//堆空间 一直可以存活到 释放或 进程结束为止
char* return_heap(){
char *p= malloc(20);
p="hello heap";
puts(p);
return p;
}
//堆栈差异
int main() {
char *b;
b=return_stack();
puts(b);
char *c;
c=return_heap();
puts(c);
free(c);
return 0;
}
十六、OJ指针
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//输入一个整型数,然后申请对应大小空间内存,然后读取一个字符串(测试用例的字符串中含有空格),
// 字符串的输入长度小于最初输入的整型数大小,最后输出输入的字符串即可(无需考虑输入的字符串过长,超过了内存大小);
int main() {
int i;
char *p,*q,c;
scanf("%d",&i);
p=(char*)malloc(i);//然后申请对应大小空间内存
q=p;
scanf("%c",&c);//去重回车\n
fgets(q,i,stdin);//这里注意字符数量 因为还要存储结束符\0 那么它肯定存储的数量为i-1
// 所以字符串的输入长度小于最初输入的整型数大小 存储i个字节的字符大小 空间大小为i
puts(p);
free(p);
return 0;
}
十七、函数
1.递归
关键:找公式 f(n) f(n-1) f(n-2) ....
退出条件
#include <stdio.h>
//假如有n个台阶,一次只能上1个台阶或2个台阶,
// 请问走到第n个台阶有几种走法?为便于读者理解题意,这里举例说明如下:假如有3个台阶,那么总计就有3种走法:第一种为每次上1个台阶,
// 上3次;第二种为先上2个台阶,再上1个台阶;第三种为先上1个台阶,再上2个台阶。输入为n,输出为走到第n个台阶有几种走法
int step(int n){
if(n==1||n==2){
return n;
}
return step(n-1)+ step(n-2);
}
int main() {
int n;
scanf("%d",&n);
printf("%d\n", step(n));
return 0;
}
2.全局变量与局部变量
全局变量与局部变量重名---就近原则
局部变量仅在离自己距离最近的大括号中进行使用
十八、结构体
注意:
结构体声明最后大括号必须加分号 ;
使用 struct student s={...}; s.sum....
结构体的大小必须是最大成员(存储字节大小)的整数倍--如果不是 那就要对齐
为了方便CPU进行读取
如果其他的成员变量存储字节之和要比最大成员变量的存储字节要小那么就会存储在一起
1.指针与结构体
struct student s={...};
*p=&s;
p->sum p->name p->sex;指针访问结构体成员变量
struct student arr[3]={...};//结构体数组
*p=&arr;
赋值string
strcpy(p->name,"Bob");
2.typedef 别名
typedef struct student{} stu, *pstu;
stu:等价于 struct student
pstu:等价于 struct student*;
typedef int INTEGER; //也可以给int起别名 方便 替换 使用INTEGER的类型
3.C++的引用
void change(int &b){}
int a=10;
change(a)
void changePointer(int * &p,*q){
p=q;
}
int i=10;
q=&i;
changePointer(p,q);