C语言自学笔记(部分)
一、指针
1.指针类型决定了指针+1进行偏移时,移动单元的大小
char *:加一个字节
int *:加4个字节
double *:加8个字节
2.维度性
int iVar = 0; //0维 int *pIVar = &IVar; //1维指向1维 int **ppIVar = &pIVar; //2维指向2维 【定义时每加一个*就升一维,读数据时正好相反,每加一个*就降一维】
3.*p = *p + 1
表示p指向的存储空间内的数值+1
4.*p(写入) = *p(读出)
除定义指针变量之外的情况,在等号左边的*,都代表向指针指向的存储单元内写入数据;在等号右边的*,都代表从指针指向的存储单元中读出数据
5.后置++:P++
是基于语句单元的运算执行完后再自增(如逗号,分号)
(a++) + b + (c++) => a + b + c;a = a + 1;c = c + 1
*++p:先p = p + 1,再*p
*p++:先*p,再p++ 【等价于*(p++),也相当于*p,再p + 1(p++要后算)】
二、数组
1.内存的动态分配(动态数组)
int *pList = (int *)malloc(sizeof(int)* 5);
*(pList + 0) = 100; 【*(pList + 0)= pList[0]】
2.指针数组
int *ipList[9] = {0}; //具有9个元素的指针数组,每个元素是地址
int **p = ipList; //p放得是指针数组的首地址
int var = 3;
ipList[2] = &var; //数组中第三个元素放入var的地址
//【= *(p + 2) = &var】
printf("%d\n", **(p + 2)); //输出var的值
//【= *p[2] = p[2][0]】
3.二维数组
int dimension[3][3];
printf("%d\n", dimension); //整个数组的首地址,sizeof值为4 * 9
printf("%d\n", dimension[0]); //第一行的首地址,sizeof的值为4 * 3
printf("%d\n", dimension + 1); //表示dimension【1】的首地址(行 + 1)
printf("%d\n", dimension[0] + 1); //表示dimension【0】【1】的地址(列 + 1)
定义数组时赋值用{ };(里面没有具体值,则int是0,char是AC的0,指针是NULL)
int dimension[3][3] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
用的时候:*(*(dimension + i)+ j)= dimension[i][j]
4.数组的指针【二维数组】
int dimension[3][4];
int (*p)[4] = dimension; //p相当于指向二维数组
p指向包含4个int数据的一维数组
用的时候:p[i][j] = dimension[i][j] = *(*(p + i) + j)
5.二维数组的动态定义
方法一:
int (*pMatrix2)[colNum] = (int (*)[colNum]) malloc(sizeof(int) * colNum * rowNum);
for(int i = 0; i < rowNum; i++)
{ //赋值
for(int j = 0; j < colNum; j++)
{
pMatrix2[i][j] = i * j;
}
}
方法二:
int *P[rowNum];
for(int i = 0; i < rowNum; i++)
{
P[i] = (int *)malloc(sizeof(int) * colNum);
}
三、结构体
1.结构体的定义
方法一:
struct Student
{
int num;
char name[20];
int age;
}; //最后要有分号,结构体相当于一种定义
struct Student student1, student2;
方法二:
struct //这种定义只能用一次,用完就没了
{
int num;
char name[20];
int age;
}student1, student[10]; //student1是结构体类型,student[10]是一个结构体数组
方法三:
typedef struct Student //重命名,Stu就是Student的结构体
{
int num;
char name[20];
int age;
}Stu;
Stu student1, student2; //定义的时候直接用Stu就行
注意:结构体定义时其成员可以是另一个结构体类型
2.结构体的引用
struct Student student = {10101, "LiMing", 18}; //定义并初始化
printf("%d %s %d", student.num, student.name, student.age);
3.结构体指针
struct Student *p;
p = &student; //要有取地址符,指向结构体student
printf("%d %s %d", (*p).num, (*p).name, (*p).age);
//注:在用结构体成员时,以下三种形式等价
// student.num
// (*p).num
// p -> num
注意:在给字符数组赋值时,只有初始化可以直接写入
如student = {10101, "LiMing", 18};
单成员赋值:
student.name = "LiMing"; //这么写是错诶的
而要用字符串复制函数:
strcpy(student.name, "LiMing"); //这样是正确的
4.结构体变量作为函数参数
void hanshu(struct Student student)
{
//...
}
//这种方式是”值传递“,在hanshu中对形参的修改,不会返回主调函数,实参的结构体内容不会受影响。【该方法用的较少】
5.结构体变量的指针作为函数的参数
void hanshu2(struct Student *pt)
{
//...
}
hanshu2(&student); //调用
//这种方式是”地址传递“,在hanshu2中对形参的修改就是对student这个结构体的修改
6.【小技巧】同类数据的统计操作
//同类标记变量
for(扫描)
{
if( )
{
//相同。。。,操作
}
else
{
//不相同,操作
//更新
}
//比较最后一次异同情况(一定要注意这一步)
}
对一堆乱序的数据,可以先排序,然后再进行处理【排序完成后,值相同的数据就在一起了】
前一次访问的数据跟现在访问的数据不相同,就说明同一类型的数据就访问结束了
四、其他知识点




浙公网安备 33010602011771号