C笔记 - 知道 1.1 \10
1 - C语言 是由 1972 年美国的 Dennis Ritchie 设计发明,并首次在 Unix 操作系统的 DECPDP-11 计算机上使用
2 - C 是由 BCPL(Basic Combined Programming Language)发展演变而来
3 - C 特点
① 简洁紧凑、方便灵活
② 运算符丰富:包含 34 中运算符
③ 数据类型丰富:具有现代语言的各种数据类型结构,指针秒杀众编程语言
④ 具有结构化的控制语句
⑤ 用函数作为程序的模块,便于实现模块化
⑥ 语法不太严格,程序设计自由度大
⑦ 允许直接访问物理地址、可进行位操作,能实现汇编语言的大部分功能,可直接对硬件进行操作
⑧ 可移植性好:基本上不需要修改就能用于各种型号的计算机和各个操作系统
⑨ 生成代码质量高,程序执行效率高:一般只比汇编语言效率低 10%-20%
......
4 - 每个 C程序 都必须有一个 main 函数,main 函数是程序的入口,其返回值 0 代表程序正常结束
5 - return | exit
① return 是返回函数调用。如果返回的是 main 函数,则意味着退出程序;如果返回的是子函数,则意味着返回函数值
② exit 是在调用处强行退出程序,无论写在那里,都是程序退出,运行一次程序就结束。exit(1) 非零表示异常退出;exit(0) 零表示正常退出
6 - 队列和栈的区别
① 队列:先进先出
② 栈:先进后出
7 - 指针常量 和 常量指针
1 char const *p; // 常量指针:本质是个指针,指针指向的内容是不可变的 2 const char *p; // 常量指针 3 char *const p; // 指针常量:本质上是个常量,指针本身是个常量不可改变,但是指向的内容可以改变
说出以下代码哪些是合法的
1 int a = 22; 2 int b = 4; 3 int const c = 21; 4 5 const int *d = &a; 6 int *const e = &b; 7 int const *const f = &a; 8 9 d = &b; // 允许 10 *d = 33; // 禁止 11 12 *e = 34; // 允许 13 e = &a; // 禁止 14 15 f = &b; // 禁止 16 *f = a; // 禁止
8 - 讲述以下代码存在的问题
① 没有给 str 分配内存空间,将会发生异常。注:将一个字符串复制进一个字符变量指针所指的地址,虽然可以输出正确的结果,但是因为越界进行内在读写而导致程序崩溃
1 int main(int argc, const char * argv[]) { 2 3 char a; 4 char *str = &a; 5 strcpy(str,"hello"); 6 printf(str); 7 8 return 0; 9 }
② "AAA" 是字符常量,所以在刚开始声明指针 s 时就有问题,应是 const char *s = "AAA"; 又因为是字符串常量,所以 s[0] 重新赋值的操作同样不合法
int main(int argc, const char * argv[]) { char *s = "AAA"; s[0] = 'B'; printf("%s",s); return 0; }
③ 程序运行崩溃: test1 中的 malloc 并不会返回动态内存
1 void test1(char *p){ 2 3 p = (char*)malloc(100); 4 } 5 6 int main(int argc, const char * argv[]) { 7 8 char *str = NULL; 9 test1(str); 10 strcpy(str,"hello C++"); 11 printf("%s",str); 12 free(str); 13 14 return 0; 15 }
④ 注意区分指针类型
int a[6] = {1,2,3,4,5,6}; // &a 它是数组指针,类型是 int(*)[6]; int *p = (int *)(&a + 3); // (&a + 3) 实际上表示的是 a[18] // p 是整型指针。减去 13 就是 a[18 - 13],即输出 a[5] printf("输出结果:%d 和 %d\n",*(a+2),*(p-13)); // 输出结果:3 和 6
a 和 &a 地址虽然是一样的,但其代表的意思不一样:a 是数组的首地址 a[0],a+1 就是数组中下一元素的地址 a[1];而 &a 是数组对象的首地址,&a+1 表达的是下一个对象的地址 a[0+6]
9 - const 关键字的作用
① 表示常量:不可以修改的变量
② 修饰参数:作为输入参数
③ 修饰函数:防止意外改动
④ 修饰类的成员函数:不改变类中的数据成员
10 - 指针
1 int (*s[10])(int) // 函数指针数组:每个指针指向一个 int func(int param) 的函数 2 int *p[n] // 指针数组:每个元素均是指向整型数据的只指针 3 int (*p)[n] // p 是指向一维数组的指针,这个一维数组有 n 个整型数据 4 5 int *p() // 指针函数:返回值是一个指针 6 int(*p)(); // 函数指针:指向函数的指针
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)