1、sizeof()
sizeof()是一种单目操作符,是用来计算你所使用的操作数所占的空间字节大小。
可以以类型、指针、数组和函数等作为参数,返回值类型为unsigned int。
2、strlen
strlen 是一个函数,它用来计算指定字符串 str 的长度,但不包括结束字符(即 null 字符)。
#include
#include
int main()
{
char a[] = "abc";
int b;
int c;
printf("%d\n",sizeof(a));
printf("%d\n",strlen(a));
return 0;
}
输出结果
4
3
1.int argc 整型变量
2.char *argv[] 字符指针的数组,通俗一点就是字符串数组,每个元素都是字符串
3.char *envp[] 字符串数组
1.作用域不同:全局变量的作用域为整个程序,局部变量的作用域为当前语句块;
2.内存储存方式:全局变量存储在全局数据区,局部变量存储在栈上;
3.生命周期不同:全局变量的生命周期和程序一样,局部变量随着语句块的结束而结束;
4.当局部变量与全局变量同名时,优先使用局部变量。
运行程序的内存分为堆区、栈区、BSS区、数据区(初始化)、代码区。
//main.cpp
int a=0; //全局初始化区
char *p1; //全局未初始化区
main()
{
int b;栈
char s[] = ”abc”; //栈
char p2; //栈
char p3=”123456″; //123456\0 在常量区,p3 在栈上。
static int c=0; //全局(静态)初始化区
p1 = (char)malloc(10);
p2 = (char)malloc(20); //分配得来得 10 和 20 字节的区域就在堆区。
strcpy(p1,”123456″); //123456\0 放在常量区,编译器可能会将它与 p3 所向”123456″优化成一个地方。
}
从静态存储区分配
内存在程序编译的时候已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。
在栈上创建
在执行函数时,函数内局部变量的存储单元可以在栈上创建,函数执行结束时,这些内存单元会自动被释放。
栈内存分配运算内置于处理器的指令集,效率高,但是分配的内存容量有限。
从堆上分配
动态内存分配。
程序在运行的时候使用malloc或者new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。
动态内存的生命周期有程序员决定,使用非常灵活,但如果在堆上分配了空间,既有责任回收它,否则运行的程序会出现内存泄漏,频繁的分配和释放不同大小的堆空间将会产生内存碎片。
结构体中,各成员占有自己的储存空间,总大小等于各成员的大小之和。
联合体中,所有成员公用一块储存空间,其大小等于联合体中最大成员的大小。
指针函数
指针函数是指带指针的函数,即本质是一个函数。函数返回类型是某一类型的指针
类型标识符 *函数名(参数表)
int *f(x,y);
函数指针
函数指针是指向函数的指针变量,即本质是一个指针变量,这个指针指向的对象是一个数组。
int (f) (int x); /* 声明一个函数指针 */
f=func; /* 将func函数的首地址赋给指针f */
这个特殊的指针指向一个返回整型值的函数。
例如:
void (*fptr)();
把函数的地址赋值给函数指针,可以采用下面两种形式:
fptr=&Function;
fptr=Function;
最简单的辨别方式就是看函数名前面的指针号有没有被括号()包含,如果被包含就是函数指针,反之则是指针函数。*
指针自增自减是改变指针所指向的对象,变量自增自减是改变变量的值;
#include
与#include "stdio.h"
的区别?"stdio.h"
表示的是该文件在用户当前的工作目录下
#define MAX(X,Y) ((X)>(Y)?(X):(Y))
#define MIN(X,Y) ((X)<(Y)?(X):(Y))
三目运算符:(a ? y : z
)
先判断条件 a 真假,如果 a 的值为 true ,那么返回表达式 y 的计算结果;否则,计算 z 的值,返回表达式 z 的计算结果。
(1)static 全局变量 :表示该变量是静态全局变量,在当前文件的全局内可访问。
(2)static 函数 :该函数为静态函数,只能在本文件中调用;静态函数在内存中只有一份,普通函数在内存中只有一份拷贝。
(3)static局部变量:为静态局部变量,只初始化一次,之后调用函数都是上次函数退出的值。这个局部变量在函数执行完成之后不会被释放,而是继续保留在内存中。
(4)static成员函数:表示这个函数为全类所共有,而且只能访问静态成员变量。
(5)static成员变量:表示这个成员为全类所共有。
(1)const 常量:定义时就初始化,以后不能更改。
const 形参:该形参在函数里不能改变
func(const int a)
{
};
const修饰类成员函数:该函数对成员变量只能进行只读操作
(2)修饰数组:修饰符const可以用在类型说明符前,也可以用在类型说明符后;例如:int const a[5]={1,2,3};或 const int a[5]={1,2,3};
(3)修饰常指针:const int *A; //const修饰指针指向的对象,指针可变,指针指向的对象不可变;
举例:
int const *A; //修饰指针指向的对象,指针可变,指针指向的对象不可变;
int *const A;//const修饰指针,指针不可变,指针指向的对象可变;
const int *x ---->x的地址可以输出但是数据不能输出
int const *x ---->x的地址可以输出但是数据不能输出
int *const x ---->x的地址不可以输出但是数据可以输出
const int *const x ---->x的地址和数据都不能输出
总结:左数右址 (数表示数据,指表示变量的地址 ,左右就是const在指针变量的左边或者右边)
malloc是从堆上动态申请内存空间,malloc只有一个参数,即要分配的内存大小。malloc不能对内存初始化。
int* p;
p = (int *) malloc (sizeof(int));
malloc 函数返回的是 void * 类型,必须通过 (int *) 来将强制转换。
malloc函数在动态分配数组空间时,只会增大空间,不会减小空间,所以说如果不释放内存,可能会造成内存溢出。因为如果地址没了,内存被占了但是还无法调用,就很难受。
所以此时我们调用free();
函数释放内存
一般地,对应每个malloc()调用,应该调用一次 free()函数free ()的参数是先前malloc ()返回的地址,它释放先前分配的内存。
char*strcpy(char *dest, const char *src);
int sprintf(char*str, const char *format, ...);
void *memcpy(void*dest, const void *src, size_t n)
复制的内容不同。
strcpy只能复制字符串;sprintf 函数操作的对象 不限于字符串;而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。
复制的方法不同。
strcpy不需要指定长度,它遇到被复制字符的串结束符"\0"才结束,所以容易溢出。memcpy则是根据其第3个参数决定复制的长度。
用途不同。
通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy。
sprintf主要用来实现(字符串或基本数据类型)向字符串的转换 功能。