- 在同一个工程项目中,全局变量可通用,如果要A类要用的B类的全局变量num,则这样声明,extern int num,然后就可以使用了,调用其他文件函数也是extern void func();
- #define MAX 10, 这个常量,可以使用在arr(MAX),#undef MAX则会取消这个宏
- enum Season{ };注意大括号后面的分号不可少,各成员用逗号隔开
- 普通局部变量没有初始化的话,默认赋值为随机值
- 保存字符串三种方式:一.char string[20]="hello" 二.char* str="hello" 三.char* str=(char*)malloc(10*sizeof(char)),第二种不常用
- 第三种字符串初始化的,可以用strcpy,scanf来初始化
- 一个函数中,定义static int num =100,这个局部静态变量num只会初始化一次,也就是不管你调用它多少次,都只会在第一次调用时赋值100,后面在调用的时候,num值是多少就是多少,不会重新赋值为100的
- 函数的返回值前用static修饰的函数为内部函数,它也是只能在当前的.c文件的使用
- char arr[]="abc",这个数组表示字符串,其实这个数组有4个元素,最后一个元素是\0,它表示的是字符串的结束标记
- "c:\test\32" 这里面的\32也是个转义,32是个八进制数,转化为十进制就是26,然后26对应的ASII码值的为右剪头,同理,\x61,代表是十六进制61,转化十进制就为97
- 以0开头为8进制,045,021,以0b开头为2进制,0b11101101。以0x开头为16进制,0x21458adf。%#o\n代表输出的八进制数带有前缀0,%#x\n代表输出十六进制数带有前缀0
- 输出地址的方式:%p。输出long类型的:%ld,输出double类型的:%lf,
- "%05d /n"代表输出不够时前面补0,d后面还有空格,所以它输出6个字符,%-5d/n"代表输出左对齐,%.2f/n"输出保留小数两位
- -5的二进制为11111011,过程为:原码10000101,反码11111010,补码11111011
- %lu 为 32 位无符号整数,
- 整数常量也可以带一个后缀,后缀是 U 和 L 的组合,U 表示无符号整数(unsigned),L 表示长整数(long)。
- const 定义的是变量不是常量,只是这个变量的值不允许改变是常变量!带有类型。编译运行的时候起作用存在类型检查。编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。
-
#definde N 2+3 double a; a = (float)N/(float)2; 这段代码最后输出3.5而不是2.5,因为#define是宏定义,它定义的是不带类型的常数,只进行简单的字符替换。在预编译的时候起作用,不存在类型检查,所以它运行的是2+3/2,结果是3.5,而不是运行5/2,想要是2.5,则应该定义#define N (2+3)
- static定义的变量只能在当前 c 程序文件中使用,在另一个 c 代码里面 , 即使使用 extern 关键词也不能访问这个static变量。
- int a[]={1,2}, a、(a+1)代表的是地址, (a+1) 就代表的是 a[0+1] 的地址。还有,数组名a一般都是代表首个元素的地址,但是有两种例外,第一,sizeof(a)这里的数组名代表整个数组,而不首元素,第二,&a,这里的数组名代表的是整个数组,取的也是整个数组的地址
- 注意,int* p=&a,&a+1和p+1是不一样的,前者会走一个数组的长度,后者只走了一个元素的长度,同时,printf(*p和*a)都可以打印出首元素,直接p[2]就可以取值
- 同样,int (*p)[5]=&a,*p+1和p+1也是不一样的,前者是走了一个元素长度,后者会走一个数组的长度,也就是此时p代表整个数组地址,而*p只是代表首个元素的地址
- 指针是一个变量,可以进行数值运算。数组名不是变量,不可以进行数值运算。
- struct Book b1{char name[ 20] int num };可以写b1.num=12,不能直接b1.name="xx",要写成strcpy(b1.name,"xxx"),因为num是变量,而name是数组名,同时要引入[string.h],
- struct Book* p=&b1,则可以printf("%s",p->name),也可以printf("%s",(*p).name)
- struct Stu{char name[ 20] int num} s1,s2,s3;这个是创建了三个Stu对象,而且还是全局变量,此时给这三个初始化时,在后面={"a",12,"b",13,"c",14}
- typedef struct Student{char name[ 20] int num}Stu;就是给这个类取别名,以后可以直接Stu来创建对象
- int num =getchar();这个方法相当于scanner in,而且一次只读一个字符,putchar(num)相当于system.out, (num=getchar()) !=EOF,此时不能直接输入EOF,因为它会一个个字母来认,按ctl+z可以相当于输入EOF
- scanf("%d",&a);注意它里面人传的是地址
- scanf后面如果跟着getchar(),会出现getchar()获得10的情况,那是因为,执行scanf()时,假设你输入123后,要按回车,scanf才会收到且收到的123,而输入缓冲区其实是123\n,所以123被读走了,后面getchar()看到缓冲区还有\n就直接读走了,就不等待后面的输入了,此时可以在两个中间多加个getchar()把\n读走,所以可以用while((ch=getchar())!=EOF)
- scanf()只会读取空格前面的字符,如果想读取空格后面的,可以用gets(xxx),它代表读取一行
- system("cls");执行清空屏幕,是<stdlib.h>里有,Sleep(10)是<windows.h>里的
- 比较两个字符串是否相等,不要用==,应该用strcmp("xxx","xxx"),相等的话返回0
- 变量最好定义在代码的最开始位置,不然可能会报错
- strlen()参数放的是地址,碰到“\0”时才算数完个数,不然就会是个随机数,char arr[]="adsf",strlen(arr)会报错,因为里面是一个数组指针,也就是char (*p)[5]=&arr,而strlen(const char*)不匹配,返回的是无符号整数
- typedef int INT,给int这个关键字重新起名,后面用INT就代表int,比如typedef long time_t,这个time_t其实就是long类型,
- srand((unsigned int)time(NULL))和rand()要一起使用,不然生成的随机数有问题,有srand(参数),里面参数是time(time_t *time),代表生成当前时间毫秒数,它是不停在变化,而srand(参数)它就是要一个会随时变化的参数,所以用time(),srand(xx)就是随机数生成器,只要调用一次就行,所以可以放在循环外面
- printf();
goto stand;
rand();
stand:
printf(); 上面代码是goto的用法,一般不用,在嵌套for循环里面的最后一个for循环可以用,用来跳到第一for循环,相当于JAVA中的break某个for循环 - char arr1[]="bit"; char arr2[]="#####"; strcpy(arr2,arr1);printf("%s",arr2);这代码运行时会把源字符串的所有字符包括"\0"也复制到arr2里去,arr2会变成"bit\0###",但是在输出的时候只输出"bit",那是因为printf遇到"\0"后就代表字符串已经结束,就不会打印后面的内容了
- strncpy(dest,src,n)这个是复制n个字节到dest中,而且它不会复制'/0',如果n大于src的长度,那么后面用0补满
-
char str[] = "almost every programmer should know memset!"; memset (str,'-',6); scanr("%s",str); 结果会输出----- every programmer should know memset!
- 函数swap(arr[]),当把arr这个数组传入swap函数时,不能用sizeof(arr)/sizeof(arr[0])这个来计算数组长度,因为此时的实参arr其实是代表arr[0]的地址,所以sizeof(arr)里的arr相当于一个指针,其大小要么是4KB,要么是8KB
- 引用自己定义的库用的是#include "add.h",引用非自定义的库才是<>
- 函数的声明一定要放在头文件里
- 在自定义的头文件里,比如add.h,开关加上#ifndef __ADD_H__ #define __ADD_H__这两行,在末尾在加上#endif ,这个为了避免同一个项目中反复引入同一个头文件,ifnodef意思就是如果这个头文件未被定义,如果其它人已经引入这个.h,那么这个ifnodef会是假,就不会引入了,同时,#pragma once跟它的效果一样
- printf("%d",num),如果在这句代码前一行加上#ifdef DEBUG,后一行加上#endif,代表如果宏定义了DEBUG,那么这句代码就会编译,否则就不编译,也就是可以选择性编译
- #if defined(DEBUG) 代码xxxx #endif ,这个跟上面一样,反过来就是#if !defined(DEBUG)
- 还有#if 表达式或数字 #elif 表达式或数字 #else 表达式或数字 #endif 也是一样选择性编译,表达式或数字不为0的,就编译,if的成立,elif和else的就直接不会编译,一般用于多行的注释
- sizeof()和 strlen()区别,在同是计算“abc”时,前者是4,后者是3,因为前者把"\0"也算,后者是到"\0"就打住
- 冒泡排序:就是相邻的两两比较大小,到最后那个数最大或最小,如果在第一轮并未发现交换,说明它就是有序的了,那么后面几轮就无需比较了,可以定个flag=1,如果第一轮有交换了,就flag=0,然后第一轮结束后,如果flag==1,直接break,这样可以省时
- a^b^b,这里的^是代表异或,这个表达式结果为a
- sizeof(s=(a+5)),注意,sizeof()里面不会进行真实的运算,也就是执行完后,原来的s是多少就是多少
- int arr[5]={0}; int* p=&arr[0]; *p++=0;最后一句代码意思是,先把p地址指向的内容改成0,也就是arr[0]=0,然后在p++,地址就指向了arr[1]了,而*--p=0;则是先 - -p,也就是指针向前挪一步,然后赋值0
- 规定,一个指针指向某个数组时,它可以与数组最后一个元素的后一个指针进行比较,但是不能与第一个元素的前一个指针进行比较
- int i= -1, i > sizeof(i)这个条件为真,因为sizeof()返回的是无符号数,而负数要和它比较,会把负数转成无符号数,而-1转成无符号数是个很大数,所以为真
- b=++c,c++,++a,a++;这个表达式中,因为赋值=的优先级大于逗号,所以为先算b=++c,然后在算后面几个
- 计算一个二进制有几个1,可以把>>1然后在&1,如果结果是1,就count++,然后继续>>
-
while(n){ n=n&(n-1); count++; }//这个是另一种算有几个1的方法
- for(int i =0,i<10,i++)这个是C++的语法,C的语法应该是int i=0; for(i =0,i<10,i++)
-
//这里形参加const意思是*src不能改变,如果while(*src++=*dec++)就会报错,防止你复制 //的方向反了 char* my_strcpy(char* dec, const char* src){ char* ret =dest; assert(dec != NULL);//如果成立,会抛异常,要引入assert.h头文件 assert(src != NULL); while(*dec++=*src++){ ; } return ret; }//模拟strcpy()
C language
于 2022-02-11 00:44:49 首次发布
本文详细介绍了C语言中全局变量的使用,包括extern关键字的应用,以及#define宏定义的原理。讲解了字符串的三种初始化方式,并探讨了常量、枚举和局部静态变量的特性。同时,深入讨论了指针、数组、函数指针以及内存管理,包括内存区域、字符串处理、类型转换和动态内存分配。文章还涉及了函数的调用、参数传递、运算符重载以及C++中的构造函数、析构函数和虚函数。此外,涵盖了C++的模板、异常处理和STL容器,如vector、string、deque等,以及迭代器和算法的使用。
摘要由CSDN通过智能技术生成