用变量a给出下面的定义:
1.一个整型数;int a;
2.一个指向整型数的指针;int *a;
3.一个指向指针的指针,他指向的指针是指向的一个整型数;int **a;
4.一个有十个整型数的数组;int a[10];
5.一个有十个指针的数组,该指针指向一个整型数;int *a[10];
6.一个指向有十个整型数组的指针;int (*a)[10];
7.一个指向函数的指针,该函数有个整型参数并返回一个整型数;int (*a)(int);
8.一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数;int (*a[10])(int);
定义变量或者解析定义的时候用到的左右法则:
int (*a[10])(int);
首先找到变量名a,先往右看到了【】,说明a十个数组,【】里面是个10,表明数组里有10个元素;再继续往右看遇到),这是后应调转方向往左看!遇到*,表明数组里存的元素是指针变量!继续往左看遇到了(,这时应调转方向,往右看!遇到了(),说明指针变量指向的是函数,()里是int,表明函数的形参只有一个,并且参数类型为整型,又调转方向往左看,遇到了int,说明函数返回值的类型是int 类型。
int add(int a ,int b);
函数的名 :add;
函数的形参:2个:int a,int b;
函数的返回值: int类型的返回值
左右法则:首先找到变量名,然后往右看,每次遇到括号,调转方向,直到定义解析完毕!
左值右值:
int a = 12;
在定义变量给变量赋值,叫初始化;
在定义变量后,再对变量进行操作,比如改变变量的值,叫做赋值;int a; a = 8;
变量的作用范围
全局变量:作用范围是整个.c 文件;
局部变量:作用范围是{ }所在的代码块;
数据的取值范围:
有符号:既可以表示正的也可以表示负的,最高位只表示正负,不参与存储数据,0表示正,1表示负;
无符号:只能够表示非负的,最高位参与保存有效数据;
char 为例:
signed char:
最大的:正的!-》 0111 1111 = 127
最小的:负的!-》1111 1111 = -127
存在的问题:0000 0000 = 正无穷和 1000 0000 = -0
unsigned char
最大的:1111 1111
最小的:0000 0000
原码、反码和补码:
数据在计算机里面保存的时候,都以补码的方式保存的!
正数:原码和反码补码都是一样的;
负数:负数的补码是负数的绝对值按位取反再加一;
-1的补码计算:1.负数的绝对值 2.每位先取反 3.每位再加一
例: -1 -》绝对值 0000 0001 -》每位取反1111 1110 -》每位加一1111 1111
运算符:
+、-、*、/、%、i++、++i
i++:先使用在加一:例:i = 0; printf("i= %d",i++);此时输出i等于0
++i:先加一再使用:例:i = 0;printf("i = %d",++i);此时输出i等于1
scanf(“控制格式”,地址);
作用:从终端获取输入的数据,按照‘’控制格式‘’保存到‘’地址‘’,所对应的空间里面。
例:scanf(‘'%d'’,&a);
选择语句:
if(表达式) //逻辑表达式,关系表达式,数值表达式;
{
代码;
}
else
{
代码;
}
对于if -- else
1.if表达式成立的条件;
2.else和if配对
3.if( ) 后不能加;
4.if后面的代码块要用{}
5.if--else可以嵌套使用
switch -- case语句:
{
case 判断条件1;
代码;break;
case 判断条件2;
代码;break;
。。。。。。
default:代码;
}
掌握:
1.表达式中的条件;
2.break存在和不存在的区别:break存在时遇到break就跳出语句,break不存在时,如果下面的case语句中存在break则执行到下面的break结束,如果没有break则执行全部case语句。
3.default中的break;
4.switch--case的执行过程;
循环结构:
for(语句1;语句2;语句3) //for(;;)死循环 用ctrl + c中断
{
代码;
}
执行过程:
首先执行语句1,然后再判断语句2中的条件是否满足,如果满足,进入for循环执行代码块;代码执行完毕执行语句3,然后执行语句2,判断条件是否满足,如果满足则继续执行代码块,再执行语句3,再判断。若不满足则结束for循环。
注意:语句1,2,3,可以没有但是必须要有‘’;‘’!
while(条件)
{
代码;
}
或
do
{
代码;
}while(条件); //分号不能丢!
逻辑运算符:
>,>=,<,<=, !=,==
&&(与) ||(或) !(非)
A&&B:两个都为真,输出才为真,有一个为假,就为假!
例:(i<10)&& (j>6)
注:只有当A成立,才去判断B,当两个都为真即为真,当A不为真,或B不为真即为假
A||B :只要有一个即为真就为真,当A为真时无需判断B
!A:对A取反
数组:
数组的分类:
根据维度来区分:一维数组和二维数组;
根据数据类型来区分:整型数组、字符型数组、浮点型数组。。。。。
一维数组:
1.定义:数组的数据类型 数组的名字【常量或者常量表达式】;
例:int num[2+8];
2.初始化:
int num[5] = {1,2,3,4,5};
3.计算数组元素的个数:总价/单价
printf("sizeof(num)/sizeof(int) = %d\n",sizeof(num)/sizeof(int));//此时定义的是int型的数组,若是char类型则将int改为char。
4.引用:int num[N]
下标法:数组的下标从0开始,最后一位N-1。
num[i]做左值表示空间;
num[i]做右值表示数据;
二维数组:
1.定义:数组的数据类型,数组的名字[常量或者常量表达式][常量或者常量表达式]
例:int num[3][3]
2.初始化:
int num[3][3] = {1,2,3,4,5,6,7,8,9};
int num[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
每一个字节都是有地址的!一个字节一个地址!
3.引用:int num[N][M];
下标法:数组的下标从a[0][0]开始,最后一位是a[N-1][M-1];
num[i][j]做左值,表示空间;
num[i][j]做右值,表示数据;
注意的是:二维数组在内存里面是按行进行存放的!!!
字符数组和字符串:
String str = "hello"; //string类型在C语言中没有,在C++,java中有C里面用字符数组的方式来保存字符串
strlen(str) : 表示字符串的长度;
'\0'表示的是字符串结束标识,'\0'之前的字符是字符串的有效字符
例:hello world'\0' -> '\0'称为魔数(在C语言里面用来表示特定含义的数)
->所以strlen不把'\0'计算在字符串的有效长度中
sizeof(str):表示的字符串在内存中所占字节空间的大小;
char str[100] = ''hello world''; //sizeof(str) = 100;
char str[] = "hello world"; //sizeof(str) = 5+1+5+1 = 12 ->最后一个1是'\0'
char a[] = {'h','e','l','l','o',' ','w','o','r','l','d'};
sizeof(a) = 11;
char str[11] = "hello world";
//strlen(str): 从“hello world”中的'h'开始往后依次寻找,直到'\0'为止,那么'\0'之前一直到'h',是strlen(str)的大小,因为定义的是str[11]正好能够存放"hello world";字符数组str中剩余的空间来自动添加'\0',所以会一直寻找'\0',因为'\0'位置不确定,导致strlen(str)的大小不确定
总结:字符串的实质
有固定开头和结尾,在内存中连续存放的一串字符;
函数:
2.什么是函数;
3.有了函数之后有什么好处
(1)大码更加精简,使程序模块化
(2)函数可以复用
5.函数的知识点:
(1)定义:首先明确要定义的函数具备功能
定义:
函数的返回值类型函数
{
代码块!
}
(2)声明
内部声明:编译器在进行编译时是从上往下进行编译的!
如果函数的定义在函数调用之前,可以不进行声明会报警告
有些编译器不会报警告
作用:告诉编译器函数名,函数参数列表
告诉编译器函数正确使用方法
如何声明:
方法一:把函数定义的第一行复制,加";"。
方法二:int add(int,int);
外部声明 :extern 声明前加 extern
(3)调用:
函数的调用过程其实就是实参传递到形参的过程
实参:就是调用函数时传给函数的真实值
形参:函数定义的形参列表
如何调用:实参给形参传递的时候,是把实参的数"拷贝"一份给形参。
传递方向:实参->形参,形参-/>实参
打印地址:printf("&b = %p\n",&a);
函数的形参所占用的空间是在函数调用时分配,不调用不分配,不调用不分配空间,调用结束函数所调用的形参的空间会自动释放。函数调用时是按顺序调用的(不按名字)第一个实参,拷贝给第一个形参,第二个拷贝给第二个。
注意:实参和形参的类型要一致!
函数最终返回的数据类型和上面定义的返回值类型要一致!
函数的其他知识点:
1.函数的嵌套调用:函数A里面 调用函数B;
2.函数的递归调用,也就是函数调用自己
3.return :返回上一级
exit():结束当前程序的执行
4.函数的执行有两个目的:
(1)只追求过程,不强调结果,void(空),来做函数的返回值类型
(2)保存的数据->保存的是其他变量的地址
1.定义:
int a;
int *p;"*"表示指针变量
指针的类型:int *p
指针的类型:int*//把变量名子去掉,剩下的就是指针类型
指针指向的类型,int
2.初始化;
(1)将其他一个变量的地址保存到指针变量里;int*p;