c++、c语言

代码注释没有高光,小编实在改不过来了。

编译时将函数的声明放到.h 的头文件中,相似函数类型的放在同一个.cpp文件中。

预处理和宏

预处理:
#include<iostream>
#define PI
#include <omp.h>
#endif

宏
#define PI 3.14
double len(double r){
	return 2.0 * PI * 2;
}
//宏PI可以认为就是3.14,但是PI并不是变量而是宏 

std::ostream cout;
cout << "hello." << endl;

ostream: (output stream) 被保护的无法为重新赋值给cout以外的变量
允许你在当前作用域内直接使用标准库中的名字,而不需要在每个名字前都加上 std:: 前缀。

std: 命名空间(namespace)
endl: (endline)这一行的结束,输出一个换行符
<<: 操作符

#include <iostream>

using namespace std;
int main(int argc, char ** argv)
{
    for (int i = 0; i < argc; i++)
        cout << i << ":" << argv[i] << endl;
}

数据类型

int

int i = 0; //声明一个变量,数据类型为整数型(integer),并将其初始化为零
int: 整数型
整数型一旦声明必须进行初始化,最常用初始化为零!!!!在不同架构下未进行初始化会导致错误产生

unsingned int //无符号整数型
singned int //有符号整数型
整数一般为32位,有符号型最高位是存符号的,如果是0表示正数、如果是1表示负数
无符号整数型32位全部用来存数,没有符号位,表示为正数
int默认是(singned int)有符号整数型
overflow:整数溢出

short int  		//让整数短一点,少一些字节
long int		//让整数长一点,长一些字节
long long int 	//long int不够用时,用long long
<<
#include <iostream>

using namespace std;
int main()
{
	unsingned int a =  56789;
    unsingned int b =  56789;
    unsingned int c = a * b;
    cout << "c = " << c << endl;
    cout << "sizeof(c) = " << sizeof(c) << endl; //返回c字节长度
    return 0;
}

char

char本质上来说就是一个8位数的整数

singned char;//取值范围从-128到+127
unsingned char; //取值从0到255

char标准并未规定是singned char 还是unsigned char

#include <iostream>

using namespace std;
int main()
{
	char a1 =  'C';
    char a2 =  80;
    char16_t a3 =  u'天';//16位表示汉字
    char16_t a4 =  U'依';//32位表示汉字
    cout << a1 << ":" << a2 << endl;//默认输出为字符
    cout << +a1 << ":" << +a2 << endl; //“+a1”输出为正整数
    cout << "sizeof(a1) = " << sizeof(a1) << endl; //返回a1字节长度
    cout << a3 << endl;
    cout << a3 << endl;
    return 0;
}
//此为c++11

bool

c语言的标准并没有规定bool是数据类型,其结果为true(1)false(0)。

#include <iostream>
using namespace std;

int main()
{
	bool b1 = true;
	int i = b1;
	bool b2 = -256;
	cout << "b1=" << b1 << endl;
	cout << "b2=" << b2 << endl;
}

//当一个值转成bool如果不是零,其余结果为1
//c语言中可以调用<stdbool.h>

size_t

是一个无符号整数,类型与sizeof,一般用size_t表示内存大小

<csdint>
int8_t  //有符号的8位int型    INT8_MIN   int8最小值
int16_t						INT16_MIN
int32_t						INT32_MIN
int64_t						INT64_MIN
uint8_t //无符号的8位int型	INT8_MAX  int8最大值
uint16_t					INT16_MAX
uint64_t					INT32_MAX

float

#include <iostream>
#incluse <iomanip>
using namespace std;

int main()
{
	float f1 = 1.2f;
	float f2 = f1*1000000000000;
	cout << std::fixed << std::setprecision(15) << f1 << endl;
	cout << std::fixed << std::setprecision(15) << f2 << endl;
    return 0;
}


这个代码结果f1并不是准确1.2,是因为flout数值之间无法完全表达这个区间,只能在这个数之间采样,取一些代表性的点来表示,无法用有限的位数表达所有的小数

float f1 = 2.34E+10f;//2.32乘e的10次方,f为浮点数;
float f2 = f1 + 10;//f2 == f1
//量化精度不够导致,采样时 间隔性在这个区间代表性取些点
if (fabs(f1-f2) < FLT_EPSILON) //FLT_EPSILON

doubt

双精度浮点数

算数运算

const float PI = 3.14f  //const 类型限定符 表示PI的类型和数值无法被修改 
    
auto a = 2;
auto c = 2.3; //auto 灵活的数据类型,数据类型主要看在初始化时它是什么类型,且初始化后类型不再发生改变


a++; 
++a //加加在前先增再赋值,加加在后先赋值再增

~a;//按位取反
a & b //与位运算,全1出1
a | b;//或位运算,有1出1
a ^ b;//异或运算,相同出0,不同出1
 

类型转换
int num = (int)'C'; //显示类型转换
int a1 = 1.9 //结果为1
short num_short = 650000;//会输出成负数,超出short类型二进制的范围,最高位会被置为一
float f = 17 / 5;// f结果为3.f,是整数除法,整数为是3,所以结果为3.f
float f = 17 / 5f;//f结果为3.4f,是浮点数除法,结果为3.4f

//算数运算一共四种算数操作,分别是int,long,float,double

unsigned char a = 255;
unsigned char b = 1;
int c = a + b; //c = 256 ,a会转成int型255、b会转成int型1

数组arrays

#include <iostream>  
using namespace std;

int main(){
	int num_array[5];

	for(int idx = -1; idx <= 5; idx++)
   		num_array[idx] = idx * idx;
	for(int idx = -1; idx <= 5; idx++)
    	cout << num_array[idx] << endl;
//这个代码并不会报错,而是向下移位,而且类似程序可能会超出内存边界,导致操作系统会杀死程序

	int array1[4] = {9,8,7,6};
	int array2[4];
	array2 = array1; //error! 数组是指向数组的地址也就是指针常量,无法被该代码赋值,可用下列代码进行赋值
     //array2[0] = array1[0];
     //array2[1] = array1[1];

	for(a = 0; a < 4; a++)
	{
		array1[a] = array2[a];
	}
	for(i = 0; i < 4; i++)
	{
   	 	cout << array2[i] << " ";//中间空格隔开
	} 
	cout << endl;
    
	return 0;
}  
二维数组
void int_array(float mat[][3], size_t rows, size_t cols) //二维数组第二项一定要填写,因内存为一维排列,其是用于判断内存区域。

字符串Stings

数组类型字符串
char good_ping[5] = {'g', 'o', 'o', 'd','\0'};//数组字符串结束位为字符整数0

char name[10] = {'a', 'b', 'c', '\0', 'd', 'e'};
cunt << strlen(name) << endl; //字符串长度为3

常量字符串
char name[] = "abcd"; //name[5],字符串结尾有隐藏的ascii的\0

字符串拷贝
char *strncopy(char *dest, const char *src, size_t count);//将src中count数拷贝到dest

字符串连接
char *strcat(char *dest, const char *src);//将src链接到dest后面

std::string str1 = "Hello";
std::string str2 = "world";
std::string result = str1 + str2;//string并不会检查越界问题

字符串比较
int strcmp(const char *lhs, const char *rh)//前大后小返正值,前小后大返负值,首位相同向后比,完全相同返回零

结构体、联合体、枚举类型

结构体
#include <sting.h>
#include <stdbool.h>

struct student{
	char name[4];
	int born;
	bool male;
};
int main(){
	struct student stu = {"yu", 200, true}; //stu变量数据类型是student结构体
	//strcpy(stu.name, "yu");
	//stu.bron = 200;
    //stu.male = true;
    struct student stu[100];
    stu[50] born = 203; //stu变量中第51为203
    
}
#include <sting.h>
#include <stdbool.h>

typedef //自定义类型
struct _student{
	char name[4];
	int born;
	bool male;
} student; //student 相当于struct _student //创建类型别名
int main(){
	 student stu = {"yu", 200, true}; //stu变量数据类型是student结构体
	//strcpy(stu.name, "yu");
	//stu.bron = 200;
    //stu.male = true;
    student stu[100];
    stu[50] born = 203; //stu变量中第51为203
    
}

在c++中struct与class类似,只是在public/private不同,调用相同,还要注意内存对齐

联合体
union ipv4address{
	std::uint32_t address32;
	std::uint8_t address8[4];
}//union定义接近struct,union所有成员共享一个内存。所有成员有相同的地址

指针

#include <iostream>  
using namespace std;

int main()
{
	int num = 10;
	int * p1 = NULL, * p2 = NULL; //指针变量p1,p2初始化为零(NULL)
	p1 = &num;//将指针变量p1指向num地址,&为取地址
	p2 = &num;//p1,p2指向同一内存,即num的地址
	
    cout << "num = " << num << endl;// num = 10;
    
    *P1 = 20; //*为取指针地址的值,将num的值修改为20
    cout << "num = " << num << endl;//num = 20;
    
    *P2 = 30;//将num的值修改为30
    cout << "num = " << num << endl; //num = 30;
    
    cunt << "num = " << *p1 << endl;
	return 0;
}
#include <iostream>
using namespace std;

struct student{
	char name[4];
	int born;
	bool male;
};//声明结构体

int main(){
    student stu = {"yu", 2000, true};//初始化
    student * pstu = &stu; //声明pstu指针变量,指向stu变量的地址。也就是将pstu指针,指向student结构体的首地址
    
    strncpy(pstu->name, "li", 4);//指针指向name成员变量,并将其拷贝为li
    pstu->born = 2001;
    (*pstu).born = 2002;//取指针地址值中的born
    pstu->male = false;
    
    cout << stu.name << " was born in " <<  sru.born << ". Gender :" 
        << (stu.male ? "male" : "female") << endl;
    
    printf("adderss:%p\n", pstu); //c
    cout << "address of pstu: "<< pstu << endl; //c++,取地址
    cout << "address of stu: "<< &stu << endl;
    cout << "address of name: "<< &(pstu->name) << endl;
    cout << "address of born: "<< &(pstu->born) << endl;
    cout << "address of male: "<< &(pstu->male) << endl;
    
    return 0;
}
指向指针的指针

指针本身是变量,可以再用一个指针指向该指针

#include <iostream>
using namespace std;

int main(){
    int num = 10;
    int * p = &num; //
    int ** pp = &p;
    *(*pp) = 20;//(*pp)为取pp(指向指针的指针)的值,也就是p中存储的值(num的地址),*(*pp)取num的地址

	cout << "num = " << num << endl;
    return 0;
}
指针常量
int num = 1;
int another = 2;

const int * p1 = &num; //指针指向的内容不可以透过这个指针去修改
*p1 = 3; //error
num = 3;//ok num变量自身可以修改

int * const p2 = &num; //指针指向的内容可以透过该指针修改,但是指针指向的内容无法被修改
*p2 = 3; //ok
p2  = &another; //error
指针和数组

数组可以看成指针常量,数组地址无法进行修改,对数组取地址还是数组本身,而不是指针的指针

#include <sting.h>
#include <stdbool.h>

typedef
struct student{
	char name[4];
	int born;
	bool male;
} student;

int main(){
 	student students[128];

	printf("&students = %p\n", &students); 
    printf("students = %p\n", students); 
    printf("&students[0] = %p\n", &students[0]); //地址相同
    
    student * p = students;//students 本身是个指针,将students的地址赋予p
    p[0].born = 2000;
    p[1].born = 2001;
    p[2].born = 2002;
}
//指针单手操作,指针加减,是加减元素

#include <iostream>
using namespace std;

#define print_array(arrray, n)\
for (int idx = 0; idx < (n); idx++)\
	cout << "array[" << idx << "] = " << (array)[idx] << endl;
//宏定义 ,因宏只能在一行用换行转义符(\).


int main(){
    int num[4] = {0, 1, 2, 3};
    print_array(num, 4);
    
    int * p = num +1;//int型占四字节,指针是对num向上偏移四字节,即偏移到num[1]
    p++;//指针再次偏移,到num[2]
    
    cout << "num = " << num << endl;
    cout << "p = " << p << endl;
    
    *p = 20;  //num[2] = 20
    *(p-1) = 10;// num[1] = 10,检查指针是否越界
    p[1] = 30 //num[3] = 30,
    print_array(num, 4);
    
    return 0;
}

动态内存管理

在申请内存之后,手动释放内存,未释放容易发生内存泄露

//c 申请内存采用malloc

int * p = NULL;

p = (int*) malloc(4 * sizeof(int)); //申请了四个4字节内存,并将其转化为int型,指向变量p
free(p);//释放内存
//c++,申请内存采用new或new[],new是操作符

int * p1 = new int; //new int 是个表达式,结果就是这个操作的内存地址。其调用默认初始化(default initializer)
int * p2 = new int(5);//申请一个整数初始化为5,将其地址赋值给指针p2

int * pa1 = new int[16]; //申请16乘4的字节,16个int
int * pa2 = new int[16]();//():将其初始化为零
int * pa3 = new int[16]{};//():将其初始化为零
int * pa4 = new int[16]{1, 2, 3};//将前3个赋值为1,2,3  其余置为零

student *psa1 = new student[16];//申请16个结构体,指向指针psa1
student *psa2 = new student[16]{{"li", 2000, 1}, {"li", 2000, 1}};


//释放内存(delete)
delete p1;
delete p2;

delete pa1;
delete []pa2;//因为是int型没有本质区别

delete psa1; //因为psa1是结构体,当释放内存时调用析构函数,而psa1只是调用第一个元素的析构函数,释放第一个元素的内存
delete []psa2;//psa2是调用所以元素的析构函数,释放所有内存

functions 函数

函数是为了编程更加模块化

#include <iostream>
using namespace std;

int foo(int x)
{
	x += 10;
	return x;//也是个拷贝
}

int fooa(int * p)
{
	(*p) += 10;
	return *p;
}

int main(){
	int num1 = 20;
	int nmu2 = foo(num1);//相当于将num1拷贝到x,num1值没有被修改
    
	int *p1 = &num1; //将指针p1中num1的地址拷贝到p指针中,p指针指向num1,当修改p指针的指向的值时(*p)num1也会被修改。
    int nmu2 = fooa(p1);
    
	return 0;
} 

//这个代码函数的每次调用都用进行内存的拷贝,十分占用占用内存,解决办法下面参考嘿嘿

引用(reference)

c++中的概念,c中没有。一个reference实际上是一个变量的或一个对象的别名。

#include <iostream>
using namespace std;

int foo(int &x)//数据类型后加&表示引用,当修改这个值时,num也会被修改,与指针类似,但无需进行与指针的检查以及防止指针单手操作,导致内存越界
{
	x += 10;
	return x;
}

int main(){
    int num = 10;
    int nmu2 = foo(num);
    
    cout << "num = " << num << ", nmu2 = " << nmu2 << endl;
    
    return 0;
}

//如果要防止引用对原变量或对象进行修改,可以加const数据限定符
//float mmatrix_max(const struct Maxtrix mat){}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值