![](https://img-blog.csdnimg.cn/20201014180756738.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
c语言
c语言笔记
JRliuzz
这个作者很懒,什么都没留下…
展开
-
指针数组 和 数组指针 (附第1题(冒泡排序)、第2题例题)
指针数组:指针数组可以说成是”指针的数组”,首先这个变量是一个数组,其次,”指针”修饰这个数组,意思是说这个数组的所有元素都是指针类型,在32位系统中,指针占四个字节。即 多个指针组成的数组。数组指针:数组指针可以说成是”数组的指针”,首先这个变量是一个指针,其次,”数组”修饰这个指针,意思是说这个指针存放着一个数组的首地址,或者说这个指针指向一个数组的首地址。即 指向一个数组首地址的指针。......原创 2022-03-21 13:20:47 · 114 阅读 · 0 评论 -
关于指针的含义
指针在汇编中的含义原创 2022-04-01 12:40:50 · 74 阅读 · 0 评论 -
指针的应用(关于形参)
值的传递当两个变量想用函数将变量存的值进行操作时,所引用的函数假如直接用一般变量去作为参数,会导致只是把参数的值改变了,而不会传回原来的变量中,例如在上图中,swap函数的参数是用变量a,b直接作为参数而不是用指针,就会导致最后只是a,b的值进行交换了,而x,y则并没有发生交换......原创 2022-04-05 15:10:02 · 225 阅读 · 0 评论 -
野指针,空指针
野指针若定义整型变量时不进行初始化,系统会自动分配随机值给变量。同样若定义整型指针变量不进行初始化,系统会随机分配地址给指针变量。此时这个指针叫作野指针。当对野指针进行解引用并进行赋值时,就会导致有可能将内存中 代码区、数据区、堆区中的地址赋予“其他变量”,若后续接着对这个“其他变量”进行修改,将有可能将其他各区的数据进行修改,导致很严重的错误。 ......原创 2022-04-07 01:37:28 · 1341 阅读 · 1 评论 -
关于失效指针
失效指针指向一个已删除的对象内存区域的指针。(可以通俗理解为这个指针你不知道他指向什么)。下面我们用两个简单的例子来说明一下:第一个例子:int main(){ int a = 10; int *p = NULL; if (10 == a) { int x = 100; p = &x; } printf("%d\n", *p); return 0;} 在上述代码中我们把条件判断语句中的语句称为块内作用域,也就是说X只在花括号内有效,程序成从i......原创 2022-04-09 18:35:41 · 165 阅读 · 0 评论 -
函数如何返回变量的地址
当程序编译链接成功之后,会产生可执行文件,当可执行文件执行的时候,系统将会从磁盘把文件加载到内存,代码加载到代码区,而这时的局部静态变量是加载到的数据区(data区),所以当执行完fun函数之后,虽然fun函数所占用的栈帧回收了,但是局部静态变量生存期并没有影响(静态变量是在系统进入到主函数时就被定义了)。所以最后输出*ip时的结果是10。同样,定义了全局变量,也是存储在数据区,所以也可以返回。所以,若要调用函数使用指针,并且想要不受影响,不能把块内(栈帧里)的某个变量的地址赋值给某个...原创 2022-04-11 19:52:29 · 1749 阅读 · 0 评论 -
类型对指针加一的限制(附*p++、++*p、*++p)
关于不同类型的指针变量大小 在x86(32位)的系统中,不管是什么类型的指针变量,都是只是存储数据元素的首地址,所以大小都一定是4字节。在x64(64位)的系统中,不管是什么类型的指针变量,都是只是存储数据元素的首地址,所以大小都一定是8字节。关于指针变量加一的操作首先:指针 + 1 并不是指针代表的地址值 + 1指针变量加1,即向后移动1 个位置表示指针变量指向下一个数据元素的首地址。而不是在原地址基础上加1。至于真实的地址加了多少,要看原来指针指向的数据类型是什么。......原创 2022-04-14 00:03:25 · 498 阅读 · 0 评论 -
类型与指针的关系
若三个类型的指针同时指向同一个地址,则识别的范围会不同。也就是,类型不仅对指针变量加一有影响,类型对内存的解析能力也是有影响的。数据在内存中存放遵循高低原则,也就是高字节内容存放在高地址,低字节内容存放在低地址,所以,0x12345678在内存中是这样存放的78的二进制56的二进制34的二进制12的二进制从上到下地址依次增加通常这组数据的第一个内存单元的地址, 也就是78对应的内存单元编号表示整体的内存地址,如果是int类型就取出这4个字节,...原创 2022-04-15 00:32:39 · 300 阅读 · 0 评论 -
问0x12345678是多少?
#include <stdio.h>int main(){union {int a; long b; unsigned char c; } m;m.b = 0x12345678;printf("%d\n", m.c);return 0;}0x12345678,这个是16进制的表示方法转换成2进制:1 0010 0011 0100 0101 0110 0111 1000union {int a; long b; unsigned c......原创 2022-04-15 18:31:04 · 4563 阅读 · 0 评论 -
取值 * 和取地址 & 运算符的结合
虽然&*p=&a,而且p=&a,但是&*p并不能用来作为变量去被赋值,因为&a是一个地址常量,它只能读不能写。原创 2022-04-16 19:33:25 · 387 阅读 · 0 评论 -
一月十四日 关于生存期的问题
问题一:为什么全局变量g_mid在进程执行中已经分配到data区中,但是在主函数调用Add函数时却无法使用全局变量g_mid?答:作用域是针对编译和链接的过程,生存期是针对程序的执行过程,而在编译过程中,全局变量是在Add函数后定义的,按照作用域的规定,编译是无法通过的,而编译无法通过就不能产生可执行文件,没有执行文件进程就不能执行,所以也就不存在全局变量分配到data区中而无法调用这一说法。生存期的讨论范畴是程序编译链接成功后生成了可执行文件,当程序执行时才存在分配资源给进程,最后回收资源。....原创 2022-01-15 00:35:00 · 81 阅读 · 0 评论 -
一月十五日 左值与右值
按字面意思,通俗地说。以赋值符号 = 为界,= 左边的就是左值,= 右边就是右值。 比如:(1) int b = 3;(2) int a = b;第(2)行代码,a为左值,b为右值。 更深一层,可以将 L-value 的 L, 理解成 Location,表示定位,地址。将 R-value 的 R 理解成 Read,表示读取数据。 现在的计算机数据放在内存。内存有两个很基本的属性:内存地址和内存里面放的数据。想象完全一样的箱子。每个箱子有个编号,用来区分到底是哪个箱子,箱子里面可以放东西......原创 2022-01-15 17:33:11 · 89 阅读 · 0 评论 -
关于指针,存储方式
在内存中,每8位在内存中作为一个储存单元,每8位(bit)也叫一字节(byte),作为内存单位在32位系统中,每一个存储单元用4字节(也就是32位二进制数)给自己编号,也就是说,一个地址用32位二进制数来表示。编址范围是2^32,也就是4G。在64位系统中,每一个存储单元用8字节(也就是64位二进制数)给自己编号,也就是说,一个地址用64位二进制数来表示。编址范围是2^64,也就是16777216T,但实际上只能存128G。注意:1、指针存储的是地址是用4个存储单元(一个整型变.....原创 2022-01-20 23:58:12 · 2500 阅读 · 0 评论 -
关于sizeof
sizeof是一个关键字,在编译的时候就会确定括号内的类型并计算出大小,但是在编译完成时就已经没有了++a这个表达式,所以a会依然是0而不是1原创 2022-01-22 08:58:16 · 156 阅读 · 0 评论 -
关于typedef
例如:即用了typedef关键字可以将一个数据类型换成其他名字原创 2022-01-23 12:02:19 · 445 阅读 · 0 评论 -
关于extern
例如:g_min是在fun函数和主函数后面定义的,所以在g_min定义之前的函数是不能调用的,此时有两种办法处理,一,将定义改到函数之前定义。二,使用extern关键字对变量进行声明。如下图:注意:extern关键字只对全局变量有效。......原创 2022-01-23 12:54:13 · 200 阅读 · 0 评论 -
关于静态关键字static
局部变量:fun函数的变量b是静态局部变量,所以在fun函数第一次被调用时,b被初始化,之后fun函数再次被调用就不会再次初始化了。原因是静态局部变量的空间并不在栈区,而是在数据区,就如同上图中a是在栈区,b是在数据区(数据区的数据在整个程序执行过程中都存在,栈区的数据在函数调用完时数据空间就要返还给系统)注意:1)静态全局变量或者静态局部变量在定义变量时若没有初始化,系统会自动把变量初始化为02)在c中,静态局部变量必须用常量来初始化,不能用变量初始化,如下图:..原创 2022-01-24 00:10:05 · 529 阅读 · 0 评论 -
关于宏常量
结果为29结果为80原创 2022-01-24 00:11:31 · 188 阅读 · 0 评论 -
关于register关键字
例如:for循环中的c在每一次循环中,cpu都需要将c从内存中读取到寄存器,然后将c++之后又写回到内存中,所以访问速度相对就会慢,所以可以用register关键字建议cpu将变量c存放在寄存器中以提高访问速度。注意:其中1)32位系统中,有四个通用寄存器,每个寄存器只能存放32个二进制位(也就是4字节),所以寄存器变量大小不能超过整型大小。3)假如寄存器变量是全局变量,这个寄存器就会在整个程序执行中被占用,所以不能定义全局变量为寄存器变量。但是假如是局部变量(或者形参)..原创 2022-01-25 00:38:49 · 722 阅读 · 0 评论 -
bool类型
注意:1)bool类型的变量只要等于非零数都为true。例一:例二:例三:2)bool类型大小为1字节(1byte),但是实际上只需用到一个二进制位(1bit),因为只有0(false)或1(true)两个值3)注意区别几个字符......原创 2022-01-26 19:48:57 · 10306 阅读 · 0 评论 -
关于逻辑运算符
x等于10,10的反等于0,然后0的反等于1,所以x最后是1,但是逻辑运算符中只有++和--有回写的能力,所以a依然是10原创 2022-01-28 13:36:04 · 220 阅读 · 0 评论 -
标准文件与缓冲区以及EOF关键字
其中要注意EOF关键字的用法:此时输入回车也不会结束输入,当同时按住ctrl+C才会结束输入,也就是说getchar()!=EOF用来作为判断结束循环的条件的话,就可以用来输入多行字符(即不会被换行符影响输入)。同时要注意到这些字符输入之后,换行符是算在字符串里的,也就是说换行符也是一个字符,而不是可以忽略的结束符。重要知识点:问:为什么会跳过ch=getchar();这行代码导致没等输入y或n程序就结束了?答:scanf()......原创 2022-01-30 00:50:26 · 658 阅读 · 0 评论 -
关于判断输入字符串是什么类型的if语句
判断的条件可以通过调用库函数进行优化:改写成:原创 2022-01-30 01:40:05 · 404 阅读 · 0 评论 -
三道关于if语句的题目
1)C语言—输出三个整数的最大值_一个馋女王(美杜莎)身子的程序员的博客-CSDN博客_c语言输入三个数输出最大值C语言三个整数求最大对于求三个数中最大的一个,首先定义三个整型变量a,b,c。最后把最大值赋给a,也就是三个变量互相交换使得a成为最大的那个。int a,b,c; //定义三个整型变量scanf("%d%d%d",&a,&b,&c); //从键盘输入给三个变量赋值2.编写程序求出a,b,中的最大者if(a<b) a=b; //如果a小于b,就将b的值赋给a...原创 2022-01-30 02:15:38 · 474 阅读 · 0 评论 -
关于有限状态机的运用(switch语句)
有限状态机原创 2022-02-01 14:50:15 · 660 阅读 · 0 评论 -
判断闰年题目(要求使用函数)
写一个函数判断闰年C语言_HiMark-CSDN博客_编写一个判断闰年的函数闰年:能被4整除同时不能被100整除,或者能被400整除。#include#pragma warning (disable:4996)int runnian(int n){ if (((n%100!=0) && (n%4==0)) || ( n % 400==0) ) { return 1; } else {https://blog.csdn.net/yu876876/article/details/793386..原创 2022-02-01 16:18:27 · 501 阅读 · 0 评论 -
关于循环语句
注意:while与dowhile的区别就是,dowhile会先执行一次循环体再判断是否重新进入循环,也就是会比while语句多一次循环。题目一:九九乘法表C语言小编程之九九乘法表_宇哲-CSDN博客_九九乘法表c语言编程在初学C语言中,我们会遇到很多九九乘法表的问题,在这我们进行一系列的分析。 九九乘法表的格式是x*x=x的格式。 接下来,我们要做的是利用循环结构,使得数量发生变化。在最后,要对乘法表的形状进行限定。 首先我们先进行,对 两个乘数进行循环。然后求积,最后输出,我们原创 2022-02-02 01:34:17 · 197 阅读 · 0 评论 -
break continue goto exit
一 、break注意:1)break只能跳出一层循环。2)break只能用在switch和循环语句中,其他一般用return。二、continue注意:1)如上图后两个程序语句,在while和dowhile语句中很容易出现死循环,所以一般不在while和dowhile语句中使用continue。2)在for循环中使用continue的时候假如for循环中没有循环条件会导致进入死循环。除非改成这样,就可以正常运行了。三、goto...原创 2022-02-05 20:30:32 · 302 阅读 · 0 评论 -
编程练习题
注意:输出浮点型数据时,单精度用%f,双精度用%lf。最好用双精度,因为单精度输出只有7位有效值,而双精度能达到16位。原创 2022-02-19 19:05:56 · 170 阅读 · 0 评论 -
一月十四日 可见性(作用域)和生存期
进程:程序的一次执行。 创建进程之后,系统将会给进程分配两个重要资源,一是cpu,二是内存空间(即用户空间)。当进程执行完之后,系统将会把分配给进程的资源收回。用户空间分两部分,一是代码区,用以存放代码, 二是数据区(包括数据区,堆区,栈区),用以存放数据。函数在c语言中是最小的编程单位,不允许在函数中在定义函数。1)进入主函数之前,全局变量会存进数据区(直到程序执行后)......原创 2022-01-14 22:54:28 · 163 阅读 · 0 评论 -
一月十二 关于字符串的问题
问题一:单引号内输入多个字符,为什么还能编译通过答:单引号内只能存一个字符,后面多打的字符会逐个把前面的字符覆盖,所以‘141’就是相当于‘1’也就是存入了ASCII码表中的排在49的1字符。问题二:在字符串中输入宏变量,在输出字符串时编译器是否会将宏变量识别出来并替换答:不会,定界符中的字符串的MAX不能被认为是标识符......原创 2022-01-13 14:43:24 · 75 阅读 · 0 评论 -
一月十二日 字符串常量
注意:一、只要用了双引号,就代表双引号里的是字符串,而且只要是用了双引号,就规定了用\0来结束字符串。 如上图中定义了数组存入tulun,实际上数组长度是5,但数组中不止存入了5个字母,[6]还存入了\0,而且[6]也占用了一字节的空间,但是\0并不算上入数组长度, 此外,就算在字符串最后手动加上了\0也不会影响编译器在手动输入的\0后面再加上隐藏的\n。二、若想输出在字符串中输出“或”,要在双引号前面加上\ 若想输出在字符串中输出\,要在双引号前面加......原创 2022-01-12 23:07:36 · 160 阅读 · 0 评论 -
一月十一日 转义字符
所谓转义就是把原来的意义通过加上 \ 转成其他意义没有转义意义的加上 \ 也只会是原来的意义3、单双引号的输出方法就是在前面加上\4、注意区分原创 2022-01-12 00:31:00 · 191 阅读 · 0 评论 -
一月十一日 字符常量与ASCII码
一、ASCII码10 换行 13 回车32 空格48到57 0到965到90大写A到Z 97到122小写a到z二、字符常量,字符串常量注意:1、‘’,“”,单引号和双引号不看作字符,它们称之为定界符。2、直接把a赋给char类型的ch,编译器会认为a是标识符而不是字符a,而函数中并没有定义变量a(就算定义了也只是把定义好的变量a赋给了ch,而不是把字符a赋给了ch),所以编译会出错。所以这......原创 2022-01-12 00:13:10 · 809 阅读 · 0 评论 -
一月十一日 枚举变量
枚举变量所取的值必须是枚举的值。就如上图中是枚举变量,是枚举常量。注意:1、枚举常量只能是整型。2、枚举变量取的范围只能是在枚举元素给出的范围之内。3、枚举元素可以不给值,此时的枚举值根据上一个枚举元素给的值加一4、枚举变量只能取枚举常量的标识符,不能直接取标识符被赋的数值 (C++可以直接取)......原创 2022-01-11 23:01:14 · 174 阅读 · 0 评论 -
一月八日 常量
一、宏常量注意:1.宏常量的作用是:在预编译时会进行替换2.在定义时不能加“;”,否则会把“;”也替换进去二、常变量注意:1、定义了常变量,不能再次对常变量进行赋值,只能读取......原创 2022-01-09 00:43:25 · 389 阅读 · 0 评论 -
const与指针变量的关系
const 修饰指针变量的时候:1、const 如果放在 * 的右边,修饰的是指针变量 p,表示指针变量不能被改变,但指针指向的内容可以被改变。int main(){ const int num = 10; //num = 20; //err int* const p = # int n = 100; *p = 20; //ok //p = &n; //err return 0;}2、const 如......原创 2022-04-18 12:10:06 · 169 阅读 · 0 评论 -
数组与指针的关系
数组名有两个属性一,数组元素的类型二,数组元素的个数(数组的大小)其中,在sizeof语句中,数组名是代表整个数组的意义除了sizeof语句外,其他语句中出现的数组名都代表的是数组首元素的地址,即作为指针使用。输出数组第i+1个元素,有两种方式:假如定义了数组名为ar,定义了数组指针p,一、使用下标方式表示:ar[ i]或者p[ i] (系统会自动将p[ i]转换成指针方式*(p+i))二、使用指针方式表示:*(ar+i)或者 *(p+......原创 2022-04-19 23:39:24 · 115 阅读 · 0 评论 -
数组,指针与函数的关系
数组作为形参时,假如数组传入到函数的时候,是系统分配栈帧给形参然后复制整个数组的话,会导致对时间和空间的浪费,所以假如形参是数组,数组名会退化成指针(指向首元素的地址)。 因为把数组作为形参会把数组名退化成指针,而退化之后就会丢失掉它的大小属性,所以假如调用的函数会使用到数组大小 n 的话,要记得:把数组作为形参的话,要同时把数组大小 n 也传给函数。......原创 2022-04-22 01:00:31 · 162 阅读 · 0 评论 -
ifndef/define/endif的使用
ifndef/define/endif:简而言之就是避免头文件被重复引用。(ifdef/define/endif是已定义的宏为真,ifndef/define/endif是未定义的宏为真)在一个大型软件工程编写code,可能会有多个文件同时包含一个头文件,当这些文件编译链接成一个可执行文件时,就会出现大量重定义的错误。在头文件中实用#ifndef #define #endif能避免头文件的重定义。如编写头文件ArrayList.h在头文件开头写上两行:#ifndef _Array_List_原创 2022-04-23 18:31:35 · 4161 阅读 · 0 评论