一、初始函数&数组
1.函数
函数的作用是:定义一个函数,在进行多次复杂计算时可以直接引用过来,避免函数的复杂冗长,节省内存和时间。简单来说就是:简化代码,代码复用。下面举一例子:
此程序为两数相加
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
int a = 0;
int b = 0;
int sum = 0;
scanf("%d %d",&a,&b);
sum = a + b;
printf("sum=%d\n",sum);
return 0;
}
下面是使用函数使两数相加的做法
#define _CRT_SECURE_NO_WARNINGS 1
int Add(int a, int b)
{
int z = 0;
z = a + b;
return z;
}
#include<stdio.h>
int main()
{ int x = 0;
int y = 0;
scanf("%d %d", &x, &y);
int sum = Add(x, y);
printf("%d\n", sum);
return 0;
}
虽然看起来使用函数使程序更加复杂,但是后期再出现两数相加的问题时,使用函数的程序只需要引用一下即可得出结果。
2.数组
定义:一组相同类型的元素的集合。
要存储1~10的数字,怎么存储?
int arr[10]={1,2,3,4,5,6,7,8,9,10}//定义一个整型数组最多放十个元素
c语言规定,数组中的每个数都有下标,下标从0开始计数。
二、操作符
1.算术操作符:+ - * / %
除法运算当/左右都为整数时进行的是整数运算得到的是整数,如果要得到小数,就需要使除号的一端为小数。例如:
%-----取模(取余)取两数相除的余数
9/2商4余1,故取值为1
2.移位操作符:右移操作符>>;左移操作符<<
字节与二进制的关系: 1比特 = 1个2进制位 1字节=8比特
<<左移操作符---移动的是二进制位
例如:一个整形数字2对应的二进制数为10,它对应的比特站位是:
其向左移动一个比特位后会变成
二进制100对应的十进制数字为4,故结果为4。
3.位操作符:(&)按位与;(|)按位或;(^)按位异或
4.赋值操作符:
#include<stdio.h>
int mian()
{ int a=2;
a=a+5----a+=5;
a=a-3----a-=3;
a=a%3----a%=3;
return 0;
}
5.单目操作符:(!)逻辑反操作;正负号;(&)取地址;(sizeof)操作数的的类型长度{以字节为单位}……
a+b:加号两侧有2个操作数,故加号为双目操作符。
单目操作符只有一个操作数。
“!”的作用就是把真的数变成假,把假的数变为真。
#include<stdio.h>
int mian()
{ int a=0;
printf("%d\n",!a);
//0表示假,非0表示真
return 0;
}
”sizeof“是一个操作符,计算数据类型或者变量的大小
#include<stdio.h>
int main()
{ printf("%d\n",sizeof(int));
printf("%d\n",sizeof(a));
return 0;
}
可以利用sizeof来计算数组中元素的个数
"~"对一个数的二进制按位取反:把所有二进制位中数字,1变成0,0变成1
例如:
整数在内存中存储的是补码,一个整数的二进制表示有3种:原码、补码、反码。
负数的计算:-1:10000000000000000000000000000001 (原码)
1111111111111111111111111111111111110(反码)符号位不变其他位按位取反
1111111111111111111111111111111111111(补码)反码加1
正整数:原码、反码、补码相同。
6.条件操作符:exp1?exp2:exp3
#include<stdio.h>
int main()
{
int a = 0;
int b = 3;
int max = 0;
max = a > b ? a : b; //if(a>b) max=a printf("%d\n",max);
printf("%d\n", max); //else max=b printf("%d\n",max);
return 0;
}
三、常见关键字
1.typedef
类型重命名
将unsigned int重命名为unit_1
#include<stdio.h>
typedef unsigned int unit_32
int main()
{ //观察num1和num2,这两个变量的类型是一样的
unsigned int num1=0;
uint_1 num2=0;
return 0;
}
2.static
static是用来修饰变量和函数的:1.修饰局部变量;2.修饰全局变量;3.修饰函数
static修饰局部变量,改变了局部变量的生命周期(本质上是改变了变量的存储类型)
变量被static修饰后,生命周期和全局变量一样长,从程序开始到程序结束为止
static修饰全局变量(或函数),使得这个全局变量只能在自己所在的源文件(.c)内部可以使用,其他源文件不可使用。
3.extern
声明字符,在一个工程的多个.c文件中可以通过extern来引用其他.c文件中的代码,从而简化代码
四、#define定义常量和宏
#define是一个预处理指令
1.#define定义常量
#include<stdio.h>
#define MAX 100
int main()
{ printf("%d\n", MAX);
return 0;
}
输出结果为100
2.#define定义宏
#include<stdio.h>
#define ADD(x,y) ((x)+(y))
//不应该把x,y想成一个普通的变量,它可能是一个表达式,故x、y都要括起来,整体为宏体也要括起来
int main()
{ printf("%d\n", 6*ADD(2, 3));
return 0;
}
五、指针
1.内存
内存是电脑上特别重要的存储器,计算机中所有程序的运行都是在内存中进行的。
所以为了有效地使用内存,就把内存划分成一个个小的内存单元,每个内存单元的大小是1个字节。
为了能够有效的访问到内存的每个单元,就给内存单元进行了编号,这些编号被称为该内存单元的地址。
内存从小到大依次排列为:bite(比特),byte(字节),KB,GB,TB,,PB……
注:1字节=8比特位,其余单位的换算都是1024
开始时假设:一个内存单元=1bite,在32位操作系统中,总共可以控制2^31个内存单元,也就是2^31个比特位,经过换算后得出只能控制0.5G的内存空间,而在当时2G内存空间已经比较常见,故该假设不合理,最终得出一个内存空间=1byte(字节)
#include<stdio.h>
int main()
{ int a =10;
printf("%p\n",&a); //%p是专门用来打印地址的
int* pa=&a //pa是用来存放地址的,在c语言中pa是指针变量
//*说明pa是指针变量
//int说明pa执行的对象是int类型的
*pa=20; //*解引用操作|*pa就是通过pa里面的地址找到a
return 0;
}
注:&(取地址)取出的是四个字节中的第一个字节的地址
2.大小
指针的大小:指针是用来存储字节的,指针需要多大的空间取决于地址需要多大的空间。(一个二进制位等于一个比特位)
例:32位机器上存放一个地址需要32个比特位,也就是说需要4个字节,所以指针的大小为4个字节。64位机器同理。故,指针的大小与平台的类型有关,
六、结构体
结构体是c语言中特别重要的知识点,结构体使得c语言能创建出新的类型。
比如描述学生,学生包含:名字+年龄+性别+学号这几项信息。这里只能用结构体来描述。
#include<stdio.h>
struct Stdent
{ char name[20];
int age;
float score;
};
int main()
{ struct Stdent s={"张三",18,77.5};//结构体构建和初始化
printf("1:%s %d %f\n",s.name,s.age,s.score);//打印该结构体
struct Stdent*pa=&s;
printf("2:%s %d %f\n",(*pa).name,(*pa).age,(*pa).score);
printf("3:%s %d %f",pa->name,pa->age,pa->score);
return 0;
}