day1
C : C语言内容(不专门讲解)
c 基于c语言的扩展, 头文件, 文件后缀, 编译, 输入输出,堆内存,引用,命名空间,函数
类与对象, 封装, 继承,多态
IO流,友元, 运算符重载 ,静态数据, 常量,
模板STL,C 11新特性(auto, lambda,智能指针)
C 开发平台
window–vs2017, vs2019,qtcreator ,g ±-vscode
C 基于c的扩展
第一个c 程序
1-第一个c 程序.cpp
代码语言:javascript复制#include <iostream>
int main(int argc, char **argv)
{
std::cout<<"第一个c 程序"<<std::endl;
return 0;
}
编译:
代码语言:javascript复制g -o main 1-第一个c 程序.cpp
运行:
代码语言:javascript复制gec:$./main
第一个c 程序
从第一个c 程序可以看出与c不同:
1.后缀
代码语言:javascript复制.h, .cpp, .cc, .hpp, .cxx
2.头文件
代码语言:javascript复制#include <iostream>
c 标准输入输出iostream对应c里面stdio.h
c 标准库头文件是不带.h
在c 语言中使用标准c库,
1.比如#include <stdio.h> --->#include <cstdio>
2.在c 中使用非标准库
extern "C"
{
#include "lcd.h"
}
3.输入输出
输入cin, 输出cout,在c 里面已经定义好,不需要自己定义,直接可以使用
在使用的时候前面要添加一个std::
比如:输入
代码语言:javascript复制int a=0; double b; char c[8];
std::cin >> a;
std::cin >> a >> b >> c;
比如:输出
代码语言:javascript复制int a=123; double b=23.5; char c[8]="hello";
std::cout << a <<std::endl; //这里的std::endl就相当于换行
std::cout<<a<<" "<<b<<" "<<c<<std::endl;
注意:默认cout,cin只能对基本数据类型,和字符串输入输出,其他自定义类型需要自己重载输出输入运算符
练习:
用c 的输入输出实现学生数据初始化和显示学生信息
代码语言:javascript复制#include <iostream>
struct Student{
int age;
char name[32];
int number;
};
int main(void)
{
struct Student Jack;
std::cout<<"请输入学生信息(name age number):";
std::cin>>jack.name>>jack.age>>jack.number;
std::cout<<"name:"<<jack.name<<std::endl;
std::cout<<"age:"<<jack.age<<std::endl;
std::cout<<"number:"<<jack.number<<std::endl;
return 0;
}
运行效果
代码语言:javascript复制gec:$./main
请输入学生信息(name age number):jack 19 1001
name:jack
age:19
number:1001
在c 中使用c库函数
- 标准c库函数 直接可以用c 里面自带的头文件比如, cstdio, cstdlib, cstdbool
- 非标准c库函数
自定义的库函数比如:calc.h, calc.c
calc.h
代码语言:javascript复制#ifndef _CALC_H
#define _CALC_H
int add(int a, int b);
int sub(int a, int b);
#endif
calc.c
代码语言:javascript复制#include "calc.h"
int add(int a, int b)
{
return a b;
}
int sub(int a, int b)
{
return a-b;
}
main.cpp
代码语言:javascript复制#include <iostream>
#include "calc.h"
int main(void)
{
int a=0,b=0;
std::cin>>a>>b;
int c = add(a,b);
std::cout<<c<<std::endl;
return 0;
}
编译:当有c语言源代码可以直接编译
代码语言:javascript复制g main.cpp calc.c -o main #有c源代码的时候添加头文件不能用extern "C"{#include"calc.h"}
编译:当没有c语言源代码只有c的库
1.把c语言源代码编译成库
代码语言:javascript复制gcc -o libcalc.so -shared -fPIC calc.c
2.编译c 程序使用c库
要修改main.cpp
代码语言:javascript复制#include <iostream>
extern "C" //表示里面的函数是c语言编写并且已经编译成库
{
#include "calc.h"
}
int main(void)
{
int a=0,b=0;
std::cin>>a>>b;
int c = add(a,b);
std::cout<<c<<std::endl;
return 0;
}
现在文件如下:
calc.h libcalc.so main.cpp
代码语言:javascript复制g -o main main.cpp -L./ -lcalc
#-L后是库所在的路径, -l后面接库名 ,比如libcalc.so库名就是calc
指针堆内存
指针定义:指针就是地址(内存的编号),32位系统–32位, 64位系统—64位
指针变量:用来存储地址的变量,这个变量占用空间是4字节(32位机器)或8字节(64位机器)
指针变量定义:
数据类型 *变量名称 = 地址;
int *ptr = 0x12345678; //错误
代码语言:javascript复制3-c 指针.cpp:6:13: error: invalid conversion from ‘int’ to ‘int*’ [-fpermissive]
int *ptr = 0x12345678;
^
注意:指针在赋值的时候必须保证类型一致
如果实现上面ptr赋值
代码语言:javascript复制int *ptr = (int *)0x12345678;
堆内存分配
C语言中
申请堆空间malloc, calloc, realloc, 释放堆空间 free
代码语言:javascript复制char *str = (char*)malloc(100);
free(str);
C 语言中
用new来申请堆空间, delete释放空间
申请堆空间格式:
代码语言:javascript复制数据类型 *变量名称 = new 数据类型; //申请一个对象
数据类型 *变量名称 = new 数据类型[n]; //申请n个对象
释放对空格式:
代码语言:javascript复制delete 变量名称;
delete []变量名称;
例子
代码语言:javascript复制char *astr = new char; //申请一个char对象
delete astr;
char *bstr = new char('a');//申请一个char对象并且初始化为a
delete bstr;
char *cstr = new char[100];//申请100个char对象
delete []cstr;
int *dint = new int; //申请一个int对象
delete dint;
new == malloc 构造函数
delete == free 析构函数
练习:
申请4字节的堆空间, 从终端输入数据初始化空间值, 在用char *str 指向堆空间, 并且把空间中的每一个字节数据输出(整型数)
代码语言:javascript复制#include <iostream>
#include <cstdio>
int main()
{
#if 0
int *ptr = new int;
std::cin>>ptr[0]; //*ptr==ptr[0];
char *str = (char*)ptr;
for(int i=0; i<4; i )
{
printf("%dt", str[i]); //std::cout<<(int)str[i]<<std::endl;
}
delete ptr;
#endif
int *ptr = new int;
std::cin>> std::hex >>ptr[0];
char *str = (char*)ptr;
for(int i=0; i<4; i )
{
std::cout<< std::hex <<(int)str[i]<<std::endl;
}
delete ptr;
}
命名空间
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8Z0F1rlF-1652796910004)(day1.assets/image-20220427165633744.png)]
命名空间作用:名字冲突(函数,变量,类)
定义:
代码语言:javascript复制namepace 名称{
变量, 函数, 类
};
例子:
代码语言:javascript复制namespace A
{
int data;
void showA()
{
cout<<data<<endl;
}
}
namespace B
{
int data;
void showA()
{
cout<<data<<endl;
}
}
使用命名空间
第一种方法
空间名称::成员名 (推荐写法)
代码语言:javascript复制int main(void)
{
std::cin>>B::data>>A::data;
A::show();
B::show();
}
第二种方法
using指引
代码语言:javascript复制using namespace B; //using指引
using namespace std;
int main(void)
{
cin>>data>>A::data;
A::show();
show();
}
第三种用法
using 声明
代码语言:javascript复制using namespace std;
using B::data; //using声明
int main(void)
{
cin>>data>>A::data;
A::show();
B::show();
}
空间嵌套
代码语言:javascript复制namespace AAA
{
int dataA;
namespace BBB{
int dataB;
namespace CCC{
int dataC;
}
}
}
访问:
直接通过空间名称访问
AAA::dataA;
AAA::BBB::dataB;
AAA::BBB::CCC::dataC;
用using指引
using namespace AAA; 可以直接访问dataA
using namespace AAA::BBB; 可以直接访问dataB
using 声明
using AAA::BBB::dataB;
同名空间
file1.h文件
代码语言:javascript复制namespace AAA{
int dataA;
}
file2.h文件
代码语言:javascript复制 namespace AAA{
int dataB;
}
file1.h和file2.h文件中的AAA空间是同一个
匿名空间
没有名字的空间,空间中的成员可以在本文中直接使用,不能在其他文件中使用相当与c里面的static修饰
代码语言:javascript复制namespace{
int data;
int number;
}
int main(void)
{
data = 123;
}
作业
1、简述C 中命名空间的作用。
2、 定义两个命名空间A 和 B 分别在A中和B中定义变量value
在main函数中将两个空间的value打印出来。
3、const int a; 在C 编译器中是否需要初始化,为什么?
4、在c 中怎么使用c库函数
5、c 的常用后缀有那些?
6、说下命名空间的中匿名空间的作用, 以及与c语言中的static的异同
7、结合c 中堆空间分配,测试下系统中最大可以分配多少字节的堆空间
8、根据学过的内容编写一个程序计算栈的开始位置(大概位置)—笔试题目
9、读下面程序是否有问题如果有指出改正,并且输出结果是什么?
代码语言:javascript复制char *&get_mem(int size)
{
char *ptr = new char[size];
return ptr;
}
char *req_mem(int size)
{
char ptr[size];
return ptr;
}
int main()
{
char *&ptr = get_mem(100);
const char *p = "hello world";
memcpy(ptr,p,strlen(p));
cout<<ptr<<endl;
char *mptr = req_mem(100);
memcpy(mptr,p,strlen(p));
cout<<mptr<<endl;
}