//float 型默认保留六位小数,%f前加.x表示保留几位有效小数值
float PI=3.141595 %.2f=3.14
// %p占位显示的是内存地址,%d是整形占位(十进制),%lf是double的双精度浮点型的占位,%f是单精度的浮点型占位,%c字符型占位,%o 读入八进制整数
,%X 读入十六进制整数,%s 读入一个字符串,遇空格、制表符或换行符结束
//进制的转换...
//十进制的小数转换成二进制:小数部分和2相乘,取整数,不足1取0,每次相乘都是小数部分,顺序看取整数就是转换后的结果
//原码:正数的的原码转成二进制,最高位为符号位0,负数的原码转成二进制,最高位为符号位-1
//反码:正数的反码和原码相同,负数的反码为其原码的符号位不动,其余各位取反(1<->0)
//补码:正数的补码和原码相同,负数的补码为其反码的基础上,末尾加1
//一个字节等于8个bit(8个二进制位数),short int 占用两个字节,int 占用4个字节
//有符号:字符型取值范围char(-2^7---2^7-1),int类型范围(-2^31--2^31-1)
//无符号:char(0--2^8-1),int类型范围(0--2^32-1)
//关键字volatile--防止编译器优化代码
//关键字extern--声明变量,一般情况下定义时都不写,函数里有时会用到
//关键字const--修饰的是常量,其值不可发生改变的量,只读变量(#define PI 为宏定义常量)||c语言中一般采用#define,const是不安全的
//关键字register--寄存器变量,提高效率,建议型指令,在内存中不会有地址,如果cpu有空闲寄存器,那就会生效,没有则不会(一般不使用)
//字符串%s占位符读取到\0后会停止,例如prinf("hellow \0 world")只会输出hellow,操作中一定要有\0标志,否则会乱码
//printf格式化输入和输出:
%d 整数
%f 浮点数
%lf double
在%d %f等的中间,其实还可以包含标志符、长度:
减号 - 表示左对齐
加号 + 表示数字前需要强制加上正号+或者负号-
空格 正数留空
数字 0 表示用0填充格式化的长度
//函数putchar输出字符,char ch="a",putchar(ch),putchar(97),putchar("B")格式都是可以的,括号里面的需要int类型,也可putchar('\n'),但是不能putchar('a\n'),因为putchar只读取一个字符的内容,例如输出putchar('abcd')只读出'd',无论输入多少个字符,都只会输出最后一个字符
//函数getchar接收键盘获取的字符(第一个字符abc-->a),也可用getchar()作暂时停留页面
//a++,运算中先取本身进行运算,结束后a+1;而++a进行运算时是直接将a+1代入式子中进行计算
//运算符优先级:
1.()
2.++ ,--,! ,sizeof 结合性从左到右,单目运算符
3.*,/,%
4.+,-
5.<<,>>左右移
6.>,>=,<,<=
7.==,!=
8.&按位与 (相同的保留,不同的取0 ---0101 0101
0011 1101
0001 0101)
9.^按位异或(相同取0,不同取1)
10.|按位或(相同保留,不同取1)
11.&&
12.||
13.?条件运算符-------表达式1?表达式2:表达式3(如果表达式1的值为真,选择表达式2的值为结果,否则选择表达式3)------
14.=,+=,-=,/=
15.,(逗号运算符)a=10,b=20,c=(a,b+20),printf("%d",c),c=40把逗号后面的值赋值到前面的去
//if语句:if(表达式1){},else if(表达式2){},else(表达式3){}三种配套使用,条件语句从上往下进行判断,直到出现一个条件符合,同级别就不会再进行判断了
//switch() {case 条件: 内容;break;} switch 开关语句
//do {} while(条件约束)--先执行do里的语句,再判断是否符合while里的条件约束
//goto FLAG; FLAG:语句可在各个函数中跳转
//对数组进行for循环,可以用for( int i=0; i<sizeof(arr)/sizeof(arr[0]); i++) arr为一个数组,用数组里的单位所占的总字节大小/每个数所占的字节大小,就是循环多少次的个数
//定义数组初始化默认值为0---int arr[10]={},里面十个数据都是0
//数组必须预先知道大小,不能通过用户输入大小,例如scanf,只能通过动态数组,开辟堆空间
//数组下标越界,程序会继续读取内存中的数据,可能会乱码,内存中不允许读取的数据就会乱码
//字符数组有"\0"的标志就是字符串,字符串是字符数组的一个特例,数字0等同于\0,但不等同于'0'
//scanf键盘输入以空格为结束,即不能接收输入空格
//char类型的数组没有以0(和字符'\0'等价)结尾的char类型数组就不是一个字符串,有则是字符串
//gets(str)允许输入的字符串含有空格,而scanf不允许
//fgets(str,sizeof(str),stdin),此函数可以接收空格,且规定了指定输入长度,不会溢出,输入的长度<izeof(str)-1会默认输出一个'\n'换行,把他作为字符串的一部分,例如输入:sizeof(str)=10;输入helloworld;只会输出helloworl\0,不会出现 \n,总而言之不许会有一个 \0 ;输入长度不够会出现\n ;如,输入hello,实际上是'hello\n\0'
//puts(str),输出一个字符串,在结束后自动加上'\n',遇到\0会停止
//fputs(str,stdout)格式输出;等于printf
//在不同函数中,函数中的变量名可以重名,因为作用域不同,而且存在内存中的地址也不同
//在函数调用过程中传递的参数称为实参,实际参数有具体值
//在函数调用结束,函数会在内存中销毁
//如果函数返回值类型和return语句中表达式的值不一致,则以函数返回值类型为准
//函数声明:extern 函数类型 函数名(参量)---extern可省略,声明变量或函数是不需要建立存储空间的,而定义是会建立存储空间的,如果定义的函数在主函数的下面的话,就需要在开头进行声明
//函数定义
//函数调用
//函数:exit(0)--终止程序的运行(stdlib.h)
exit(1)表示异常退出.这个1是返回给操作系统的。
exit(x)(x不为0)都表示异常退出
exit(0)表示正常退出
//include“自己的头文件名"--导入多个文件到主程序中,一般情况下最好一个头文件对应一个源文件
//所有的指针类型存储的都是内存地址,内存地址都是一个无符号16进制整型数,在32位操作系统下,所有指针类型都是4个字节大小,在64位操作系统下,所有指针类型都是8个字节大小
//&是取地址符号,是升维度的
//*是取值符号,是降维度的
//在定义指针类型时一定要和变量类型对应上
//野指针--指针变量指向一个未知的空间
//空指针是指内存地址编号为0的空间--int* p=NULL
//操作空指针对应的空间一定会报错,操作野指针对应的空间可能会报错
//void* p万能指针--可以接受任意类型变量的内存地址,在通过万能指针修改变量的值时,需要找到变量对应的指针类型
//.c 文件和.cpp文件语法有些不兼容,例如const int a=10;int*p=&a;*p=100;printf("%d\n",a),输出结果在.c文件中就是100,在.cpp的文件中就会报错
//const 修饰指针类型,可以修改指针变量的值,不可以修改指针指向内存空间的值
(int a=10;
int b=20;
const int* p=&a;
p=&b;可以改变指针变量指向的内存空间)
//const 修饰指针变量,可以修改指针指向内存空间的值
(int a=10;
int b=20;
int* const p=&a;
*p=200;可以修改p指针指向内存空间的值;但是不能修改指针p指向的地址
例如 p=&b;改变指针地址就是错误的)
---------const离谁近,就不能改变谁的值---------
//避免有个文件被include多次
1.#ifndef__SOMEFILE_H__
#define__SOMEFILE_H__
声明语句
#endif
2.#pragma once
// 两个相同类型指针相减,得到的是两个指针直接的步长,中间隔了多少个元素类型个数,并不是所占的字节大小
//指针地址上进行相加
int arr[] = { 1,2,3,4,5,6,7,8,9 };
int* p = arr; int i;
for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
{
printf("%d\n", arr[i]);
printf("%d\n", *(p++));
printf("%d\n", *(arr + i));
}
等于数组下标加多少个
//所有指针类型相减,相减结果都是int类型
//指针的加减运算和指针自己的类型有关,char类型的指针加减1,内存地址加减1,int类型的指针加减1,内存地址加减1
//指针操作数组时,下标允许是负数 --- p[-2]=*(p-2) ---
//两个指针不能相加,相除,相乘
//指针数组里存储的元素都是指针
//值传递中形参不影响实参的值
---------------------------
int swap(int a, int b)
{
int mept = a;
a = b;
b = mept;
return a+b;
}
int main()
{
int a = 10;
int b = 20;
int c=swap(a, b);
printf("%d\n", a);
printf("%d\n", b);
printf("%d\n", c);
return 0;
}
---------------------------
//指针作为函数参数,形参的级别比实参高,就能改变实参的值
---------------------------
int swap(int* a, int* b)
{
int mept = *a;
*a = *b;
*b = mept;
}
int main()
{
int a = 10;
int b = 20;
int c=swap(&a, &b);
printf("%d\n", a);
printf("%d\n", b);
return 0;
}
---------------------------
//如果您想要在函数中传递一个一维数组作为参数,您必须以下面三种方式来声明函数形式参数,这三种声明方式的结果是一样的,因为每种方式都会告诉编译器将要接收一个整型指 针。同样地,您也可以传递一个多维数组作为形式参数。
1.形式参数是一个指针
void function(int *p)
{...}
2 形式参数是一个已定义大小的数组
void function(int array[10])
{...}
3 形式参数是一个未定义大小的数组
void function(int array[])
{...}
//如果要printf的对象是char型的字符数组,直接printf("%s\n",p)指针变量前不需要加*,,但是如果printf的对象是数字型数组,则是printf("%d\n",*p).
//而对于其他除了字符数组的数据类型的数组,是不能用数组名来一次性输出它的全部元素的,只能逐个元素输出!
//存储内容不同:字符串指针变量本身是一个变量,存储的是字符串的首地址。而字符串本身存放在以该首地址为首的一块连续的内存空间中并以'\0'作为串的结束。字符数组中存储的是字符串本身
//*p是逐个输出,要想用*p输出字符数组,得用%c占位,并且用好while循环。