1、static
1)定义在全局变量前,则其他 *.c不能调用该全局变量
2)定义在函数前面,则其它*.c不能调用该函数
3)定义在局部变量前面,则无论该函数被调用多少次,该局部变量只初始化一次,之后只会保持上一次被调用的值不变。
2.局部变量的地址不能被返回
3.定义指针在使用前必须要有所指向,即先赋值
4.所有指针变量都只占4个字节(32位系统,64位是8个字节)
5.小字节序and大字节序
不同的系统内存空间存储数据的顺序不同
6.一个字母占一个字节,char类型的变量只能存一个字母,所以存储姓名需要char型数组。
7.Const的保护作用
Void show_arry(const double ar[],int n);该声明表明,指针ar指向的是常量数据,这意味着不能用ar修改该数据,也就是说可以使用ar[0],但是不能改变其值。所以const起到保护作用。
8.sizeof()与strlen()的区别
eg1、char arr[10] = "What?";
int len_one = strlen(arr);
int len_two = sizeof(arr);
cout << len_one << " and " << len_two << endl;
输出结果为:5 and 10
点评:sizeof返回定义arr数组时,编译器为其分配的数组空间大小,不关心里面存了多少数据。strlen只关心存储的数据内容,不关心空间的大小和类型。
二.枚举型
enum
{
one,
two,
three,
four,
};
其中one=0;two=one+1;three=two+1······
若
enum
{
one,
two,
three=1,
four,
};
则one=0;two=one+1;four=three+1;
三.动态存储
1)在stdlib.h文件中有函数malloc(int a)和calloc(int a,int b)可以申请空间。free(int*p)释放内存
比如说
int*p;
int n;
scanf(“please input n:%d\n”,&n);
p=malloc(sizeof(int)*n);//申请4*n个字节内存,返回申请内存的首地址
········
free(p);//释放申请的40个字节的内存,否则内存一直被占用不释放
2)void *calloc(size_t n, size_t size);
功能:
在内存的动态存储区中分配n个长度为size的连续空间,函数返回一个指向分配起始地址的指针;如果分配不成功,返回NULL。
与malloc的区别:
calloc在动态分配完内存后,自动初始化该内存空间为零,而malloc不初始化,里边数据是随机的垃圾数据。
3)realloc(p,100);
Char *PP;
PP=malloc(50);//先申请50个字节的内存
PP=Realloc(PP,100);//将原来50个字节的内存扩展到100个内存,返回现在的首地址
加上2个 a++和++a的区别。
逗号运算符运算优先级最低。比如 x=++a,++b;和x=(++a,++b)两个有什么差别?
四.String.h中包含的库函数
只能作用于字符串的库函数
1.strcpy(a,b);//将b字符串复制到a字符串
原型声明:char *strcpy(char* dest, const char *src);
头文件:#include <string.h> 和 #include <stdio.h>
功能:把从src地址开始且含有NULL结束符的字符串复制到以dest开始的地址空间
说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。
返回指向dest的指针。
2.strcat(a,b);//将字符串b接到a后面
extern char *strcat(char *dest,char *src);
作用:
把src所指字符串添加到dest结尾处(覆盖dest结尾处的'\0')。
说明:
src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。
返回指向dest的指针。
3.Strlen(a);//计算字符串a的长度
原型:extern unsigned int strlen(char *s);
头文件:string.h
格式:strlen (字符数组名)
功能:计算给定字符串的(unsigned int型)长度,不包括'\0'在内
说明:返回s的长度,不包括结束符NULL。
区别sizeof
strlen(char*)函数求的是字符串的实际长度,它求得方法是从开始到遇到第一个'\0',如果你只定义没有给它赋初值,这个结果是不定的,它会从aa首地址一直找下去,直到遇到'\0'停止。
而sizeof()返回的是变量声明后所占的内存数,不是实际长度,此外sizeof不是函数,是c语言内置的关键字,也就是编译器必须支持的,strlen是函数。
4.sizeof()
C语言中判断数据类型或者表达式长度符;不是一个函数,字节数的计算在程序编译时进行,而不是在程序执行的过程中才计算出来!
判断数据类型长度符的关键字
用法:
sizeof(类型说明符,数组名或表达式);或sizeof 变量名
定义:
sizeof是C/C++中的一个操作符(operator),简单的说其作用就是返回一个对象或者类型所占的内存字节数。
5.strcmp(a,b);//比较字符串a和b的大小
原型:extern int strcmp(const char *s1,const char *s2);
规则:
当s1<s2时,返回为负数
当s1=s2时,返回值= 0
当s1>s2时,返回正数
即:两个字符串自左向右逐个字符相比(按ASCII值大小相比较),直到出现不同的字符或遇'\0'为止。如:"A"<"B" "a">"A" "computer">"compare"
特别注意:struct studentmp(const char *s1,const char * s2)这里面只能比较字符串,即可用于比较两个字符串常量,或比较数组和字符串常量,不能比较数字等其他形式的参数。
作用于内存的库函数
6.Memcpy(a,b,40);//将b中40个字节复制到a中,其中a和b可以不是字符串
函数原型:void *memcpy(void *dest, const void *src, size_t n);
功能:
从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中返回指向dest的指针。
所需头文件编辑
C语言:#include<string.h>
C++:#include<cstring>
说明:
1.src和dest所指的内存区域可能重叠,但是如果src和dest所指的内存区域重叠,那么这个函数并不能够确保src所在重叠区域在拷贝之前不被覆盖。而使用memmove可以用来处理重叠区域,函数返回指向dest的指针.
2.如果目标数组destin本身已有数据,执行memcpy()后,将覆盖原有数据(最多覆盖n)。如果要追加数据,则每次执行memcpy后,要将目标数组地址增加到你要追加数据的地址。
注意:
src和dest都不一定是数组,任意的可读写的空间均可。
strcpy和memcpy主要有以下3方面的区别:
1、复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。
2、复制的方法不同。strcpy不需要指定长度,它遇到被复制字符的串结束符"\0"才结束,所以容易溢出。memcpy则是根据其第3个参数决定复制的长度。两种方法都要保证dest有足够的空间,strcpy也并不比memcpy容易溢出啊。只是不是字符串不能使用strcpy。
3、用途不同。通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy
7.Memset(a,0,40);//将a前40字节全部赋值0;常用于数组清零
原型:void *memset(void *s, int ch, size_t n);
函数解释:
将s中前n个字节 (typedef unsigned int size_t )用 ch 替换并返回 s ,其返回值为指向S的指针。。
作用:
在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法
8.Memmove(a,b,40);//将b的内容移动到a的位置
原型:void *memmove( void* dest, const void* src, size_t count );
头文件:<string.h>
功能:
由src所指内存区域复制count个字节到dest所指内存区域。函数返回指向dest的指针。如果目标区域和源区域有重叠的话,memmove能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中。但复制后src内容会被更改。但是当目标区域与源区域没有重叠则和memcpy函数功能相同。
memmove的处理措施:
(1)当源内存的首地址等于目标内存的首地址时,不进行任何拷贝
(2)当源内存的首地址大于目标内存的首地址时,实行正向拷贝
(3)当源内存的首地址小于目标内存的首地址时,实行反向拷贝
五.递归函数
注意:能用循环的尽量不用递归,循环解决不了再用递归;
递归实例:
0 1 2 3 4 5 6 7 ····n
1 1 2 3 5 8 13 21 ···an
要求实现输入n显示对应的an
#include <stdio.h>
int digui(int n)
{
int am,bm,cm;
if(0==n)
{
return 1;
}
if(1==n)
{
return 1;
}
else
{
am = digui(n-2);
bm = digui(n-1);
cm = am+bm;
return cm;
}
}
int main()
{
int an=0;
int n;
scanf("%d",&n);
an = digui(n);
printf("%d\n",an);
}
六.三元运算符
如名字表示的三元运算符需要三个操作数。
语法为:条件表达式?表达式1:表达式2。
说明:问号前面的位置是判断的条件,判断结果为bool型,为true时调用表达式1,为false时调用表达式2。
其逻辑为:“如果为真执行第一个,否则执行第二个。”
Eg:
Num =( i > 100)?0:20;
(I>100)?(num = 0:(num = 20));