各部分重难点
摘抄+补充
原文借鉴
1.数组篇
一维数组
1.数组定义之后,数组名不能为左值。
int arr[3]={1,2,3};
int brr[3]={4,5,6};
arr=brr; //错误->要一个个遍历
2.错误的数组定义方式:
int arr[];
arr={1,2,3,4};// 这样的一起赋值只能在初始赋值的时候使用
int n = 5;
arr[n]={1,2,3,4,5};
这个**对的**:
int k = 3;
static int a[10];
a[k - 2] = a[9] + 1;
printf("%d", a[1]); // 输出 a[1]=1;
**错的**:
int k = 3;
```c
int a[k] = { 0,1,2 };
**二维数组**
定义:
数据类型 数组名[二维长度][一维长度]={};
可以写成:
数据类型 数组名[][一维长度]={1,2,3,4,5};
二维长度可以不写,但一维长度必须写。
2.函数篇
main函数:
是C语言函数的入口,一个程序运行之后指定调用main函数。
自定义函数:
返回值类型 函数名(形参列表){
函数体;
}
**递归函数**:函数内部自己调用自己!
举个例子:
判断一个数是否是严格递增数组
f(arr,n)
n=1 1;
n=2 arr(1)>arr(0)
n>3 f(arr,n-1)&&arr[n-2]<arr[n-1]
**快速排序**
递归调用的思想:
先记录一个基准值(最左边的值)key
记录左闭区间的下标i与右闭区间的下标j
只要i<j
从右边开始往左边找到一个数值小于基准值放到arr[i]处
从左边开始往右边找到一个数值大于基准值放到arr[j]处
上面的循环结束之后
arr[i]=key
对左半区间与右边区间重复上述步骤即可
3.指针篇
**指针即内存地址**
1.未初始化的指针变量称为野指针(非常危险)//char *p;
2.空指针即保存NULL的指针变量不能取*运算,所以需要判断指针是否为空指针。
3.下标运算符[]
arr[i]==*[arr+i];
i[arr]==arr[i];
连续在一起的 & 与 *可以相互抵消
&arr[0]=&(*(arr+0))=arr ,因此arr是取数组元素的首地址.
4.指针加法:
int n = 10;
int *p=&n;
p+1表示地址偏移了一个单位的地址空间。
char * 单位为1个字节;
int * 单位为4个字节;
float * 单位为4个字节;
double * 单位为8个字节;
*p++ 结果是*p,表示p=p+1;//但因为p++表示变换之前是数 所以认识原p 见下图
(*p)++ 结果是*p,表示*p=*p+1;
4.字符串篇
c语言中字符串以3种形式存在:
1.字符串字面值(保存在代码区不可以被修改),以"xxx"形式存在。
2.字符数组(保存在栈区可以被修改)。
3.字符指针:没有保存字符串的内容,只保存记录了字符串的首地址。
strlen和sizeof的区别:
strlen是求一个地址内存中到‘\0’为止有多少个字符。
sizeof是求变量、数组、指针、数据所占的字节数量。
#include<stdio.h>
#include<math.h>
#include<string.h>
int main()
{
int a[k] = { 0,1,2 };*/
char a[20] = { "hello world" };
int y = strlen(a);
printf("%d", y); //11 读到'\0'为止
return 0;
}