C语言中级

《c语言中级》 知识点总结:
1. sizeof关键字:
编译时确定,sizeof(对象),sizeof(类型),sizeof 对象,sizeof(指针)=4.
int a[5];   sizeof(a) = 20;   sizeof(&a) = 20;
2. c语言不允许定义空结构体; c++允许, sizeof() = 1
3. char *a = “hello” “world”; //a为”helloworld”
pintf(“\32” “3\n”) = printf(“\323”);
printf(“\172\n”);//八进制172 ascii对应值
printf(“\0x60”);//十六进制60h ascii对应值
printf(“\60” “3\n”);// 03
4. a[0] = *(a+0), 是一个表达式,0[a]也行,a代表数组第一个元素的首地址。
int a[10];  &a+1指向了a[9]后面,整行加一
对数组名求址&a会导致数组维数上升,变成了数组指针int (*)[10]
5. 有符号数和无符号数运算,结果转化为无符号数。
static int i = 10; 指定i本文件使用
extern int a;/ extern a;  声明a来自其他文件
6. const的作用
const  int x = 2; 或者 int const x = 2;
const  int *a 或者 int const *a; //a可变,a指向的对象不可变;
int * const a; //const修饰指针a,指针a不可变。
const可以修饰输入参数、返回值、成员函数
7. const指针
一个指向const对象的指针不能赋值给指向非const对象的指针,但反过来可以
(非const可以赋给const)
(1).const int i = 10;
const int *p = &i;   //p指向const int
int *q = p; //非法
(2).const int i = 10;
const int **p1;
int *p2;
p1 = &p2;
*p1 = &i; //相当于p2 = &i,但直接p2 = &i非法
*p2 = 20;//修改了常量const int,具体结果在环境上测试
8. typedef int array[10];  //typedef int[10] array;
array a;
array b[5]; //b[5][10]
array *c; //(*c)[10] , (*c)[10]要用二维数组赋值,++往下移动一行
array *c[4];// int (*c[4])[10],指向二维数组的指针数组
一维数组int a[10]中的a等价于定义了一个指向元素的指针---> int * const a;
二维数组int b[3][4]的b等价于定义了一个指向一维数组为元素的指针--->int (*const b)[4]
int b[3][5];   
*(*(b+2)+0) b中第二行第0列的值;
*(b+2) b中第二行首地址,*()有降维的作用
b+2 为b[2][0]的地址,类型为int[][5],没降维
9. 结构体对齐规则
 (1).结构体中变量的首地址能被该成员大小与对齐基数中的较小者所整除;
 (2).结构体总大小为结构体最宽基本类型成员大小与对齐基数中的较小者的整数倍,不足时填充。
 (3).确定偏移位置及大小时,将复合类型(如结构体)当做一个整体看待。
 struct a                                      struct b
 { int ii;                                       { int i;
  double dd;                                   struct a a;
 }aa;                                          double d;
 sizeof(aa) = 16;        }b;
                                             sizeof(bb) = 32;
10. scanf
scanf用%c格式输入时,空格和转义字符都为有效输入;
输出% 需要printf(“%%”);  \a鸣响   %[字符集]  %[^\n]  %i
11. 常量
#define   const    字面常量    枚举
12. 头文件 < > 与 “”
<  > 直接在系统默认路径下找,找不到就报链接错误;
“  “ 先在当前路径下找,找不到再在系统路径下找,再找不到就返回链接错误
13. 数据类型决定:(1). 数据占用内存空间大小;(2).存储格式; (3).运算规则---行为
存储类型决定: 存储区域,区域决定了作用范围和生命周期。
14. 内存分区
c++内存分为五个区: 堆(new)、栈(局部变量、函数参数)、全局/静态存储区、自由存储区(malloc)、常量区。
c语言分为四个区: 堆(malloc)、栈(局部变量、函数参数)、全局/静态存储区、常量区。
15. 堆区内存使用四要素:
int *p = (int*)malloc(10*sizeof(int));
if (null == p) return;
free(p);
p = null;
16. <malloc.h> _msize(p); 返回内存堆空间的大小
17. 千万不要返回指向栈内存的指针和引用,可以返回静态局部变量,静态局部变量在函数外存在但不可见。
18. typedef陷阱
typedef char* pstr;
定义const pstr,我们希望是const char *,但实际是char * const
19. 指针
(1).无类型指针void*p,不能加减一个整数,只能进行赋值、比较、sizeof操作。
(2).static 局部变量指针必须用全局变量初始化;
(3).不同类型的指针不能求差, 指针差为(字节数/类型) sizeof(&a[5]-&a[0]) = 4;
(4).int a[10]; a是个常量,一个地址; vc sizeof(&a)=40;   gun sizeof(&a) = 4;
(5). int a [8][9];  int(*p)[9] = a;
(6). char *p = “abcd”; p[0]=’m’; //非法,p指向常量区,不能修改;
(7).char *p = “hello”; //错误的写法,因为p指向了常量区,而p是指向变量的指针,意味着可修改所指数据,应该改为const char *p = “hello”.
(8). 任何类型的指针大小都为4个字节。
22. 指针与const
(1) int (2) * (3) p;   (1)和(2)位置:p指向的不能修改    (3)位置:p不能修改
char **p;       p----> char * ----> char;
const char**p   p----> const char * ---->const ch
char * const *p  p---->char * const ----->char  
20. 函数与指针
函数的返回值和形参列表共同构成函数类型;
typedef float (*pf) (int,double)  //函数指针
int (*p)[3]; //二维数组指针,大元素,每行有三列
int *ptr[3][4];//二维指针数组
int *(*ptr)[4];//指向二维指针数组的指针
int (*myfun())(int *, int *)//定义一个函数,返回类型为函数指针
int (*s[10])(int) //含有10个函数指针的数组
char(*(*fun())[4])(int *p)
----> char(*)(int *p)  (*)[4]  fun()//定义了一个函数,返回类型为指向二维数组的指针,数组的元素也为函数指针
char (*(*(*q)())[5])()      
---->char (*)()   (*)[5]  (*q)() //定义了一个函数指针,指向的函数返回类型为指向二维数组的指针,数组中的元素也是一个函数指针
21. 指针与函数参数
指向指针的指针作为形参,如void f(int **pp),作用是对作为指针的实参传址,如f(&p);
函数名是地址常量,可赋值给对应的指针变量----函数指针
 函数指针赋值: pfun = 函数名: 把函数名看做函数的入口地址
                 pfun = &函数名: 把函数看做名字,取其地址
 调用:  (*pfun)(实参列表)
     pfun(实参列表)
 void myfun(int x) {printf(“%d”,x);}
 void main {
  void (*pfun)();
  pfun = myfun;
  myfun(10);  //四种调用方式都是ok的
  (*myfun)(10);
  pfun(10);
  (*pfun)(10);
 }
22. (1).不要在函数调用处(参数列表中)写表达式;
(2).后++,求值时间要后到整个表达式求完值后,参数中的后++到形实结合后++;
(3).函数调用结果只能用于初始化非静态变量,static char *p = (char *)malloc(20)---->错误;
(4).static不作用与形参,会失去静态性;
(5).避免函数有记忆功能(不要使用static局部变量);函数中少修改static全局变量,避免影响其他函数;
(6).函数默认有extern修饰,函数和全局变量可以用static修饰限定为本文件使用;
(7).两层循环,多的应该放里面,减少循环次数。
23. 预处理
 (1).预处理语句以#开头,不加”;”,独占一行,可放于任意位置;
 (2).预处理在编译之前,条件编译、宏、条件包含;
 (3).预处理之前还有预处理:消除续行,检查函数名,去掉注释;
 (4).宏定义不是C语句,不是函数,不是类型定义,宏值多于一项一定要加(),防止优先级错误;
 (5).宏中的’#’使变量字符串化;
 (6).宏中的’##’使变量连接起来,#define TEST(a,b) a##b  TEST(2,3); --->23;
 (7).宏的参数不能用表达式;
 (8).用const取代无参宏,用inline取代有参宏;
 (9). (void)printf(“Beijing.\n”); void显式抛弃返回值.
24. 头文件
(1).头文件包含会引发重复定义变量,可以用条件编译解决:
#ifndef _FILENAME_H_
#define _FILENAME_H_
#endif
(2).头文件中不要定义较大的static全局变量,如结构数组等;

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值