C++指针
指针
指针和数字
从概念上看, 指针和整数是截然不同的类型。
整数是可以执行加、减。。。等运算的数字,而指针是描述的位置。因此,不能简单的将整数赋给指针;
int * pt;
pt = 0xB8000000; 这种是错误的
0xB8000000 是组合段偏移地址, 是老师计算机系统中视频内存的, 但这条语句并么有告诉程序, 这个数字是一个地址。所以需要强制类型转换;
int * pt;
pt = (int *) 0xB8000000;
使用new来分配内存(变量是存放在栈stack的内存里面, 而new从堆heap或者自由存储free store去分配内存)
指针初始化为变量的地址, 变量是在编译时分配的有名称的内存, 而指针只是为通过名称直接访问的内存提供了一个别名。
指针的真正用武之地在于, 在运行阶段分配未命名的内存以存储值。在这种情况下, 只能通过指针来访问内存。
在c语言中可以用malloc()来分配内存, 在c++中仍然可以这样做,但c++还有更好的方法, new运算符。
int *pn = new int;
new运算符根据类型来确定需要多少字节。并返回地址。在这里我们说pn指向一个数据对象, 这里的“对象”不是“面向对象编程”中的对象,而是一样东西。 术语“数据对象”比“变量” 更通用, 它指的是
为数据项分配的内存块。,因此pn指向的是内存
#include <iostream> int main(int argc, char const *argv[]) { using namespace std; int i = 10; int * p = new int; int * b = &i; std::cout << "p:" << p << '\n'; *p = 1001; std::cout << "p:" << p << '\n'; std::cout << "*p:" << *p << '\n'; delete p; // delete p; //not ok now // delete b; // not ok now return 0; };
那么我们要来思考一个问题, 就是内存被耗尽, 计算机可能没有足够的内存而无法满足new请求, 这种情况会引发异常。
使用new创建动态数组
对于小型数据对象来说,声明一个变量, 比使用new和指针更简单。但对于大型数据(如数组,字符串和结构), 应使用new, 这正是new的用武之地。
同时|:
1.静态联编:如果通过声明来创建数组, 在编译时给数组分配内存被被称为静态联编 2. 动态联编:使用new时, 运行阶段需要数组, 则创建它, 不需要,就不创建, 还可以选择长度, 被称为动态联编。
#include <iostream> int main(int argc, char const *argv[]) { using namespace std; int * i = new int [3]; std::cout << "i:" << i << '\n'; i[0] = 0; i[1] = 1; i[2] = 2; std::cout << "i[0]:" << i[0] << '\n'; std::cout << "i[1]:" << i[1] << '\n'; std::cout << "i[2]:" << i[2] << '\n'; i += 1; // 所以这种操作是错误的 std::cout << "i" << i << '\n'; std::cout << "i[0]:" << i[0] << '\n'; std::cout << "i[1]:" << i[1] << '\n'; std::cout << "i[2]:" << i[2] << '\n'; delete [] i; return 0; }
但是为撒子delete了以后就错了, 由于i是new出来的, 在堆里面, 越界操作就是野指针,所以delete的时候找不到,系统会报错。
使用delete释放内存
C++的魅力之一就是使用new请求来内存管理。另一方面就是使用delete, 那么delete用法:
int * pt = new int; short * ps = new short [500]; delete pt; delete [] ps;
需要遵守的规则:
1. 不要使用delete来释放不是new分配的内存
2. 不要使用delete释放同一内存块2次
3. 如果使用new【】为数组分配内存, 则应使用delete【】释放。
4. 如果使用new为一个实体分配内存, 则应使用delete(没有方括号)来释放。
5.对空指针应用delete是安全的
指针代码块
int -- float
#include <iostream> #include <cstring> // int /* int main(int argc, char const *argv[]) { using namespace std; int b=12; int * a = &b; int * c; c = &b; std::cout << c << ";" << a << '\n'; std::cout << *c << '\n'; std::cout << *a << '\n'; return 0; } */ /* int main(int argc, char const *argv[]) { int * b = (int *)11; std::cout << b << '\n'; int *p = new int; *p = 1001; std::cout << *p << '\n'; delete p; return 0; } */
char
// str /* int main(int argc, char const *argv[]) { using namespace std; char a[] = "abc"; char * b = a; std::cout << b << '\n'; char * c = new char[strlen(a) + 1]; c = a; std::cout << a << '\n'; delete [] c; return 0; } */
list
// list /* int main(int argc, char const *argv[]) { using namespace std; int a[] = {1,2,3}; int b[2][2] = {{1, 2}, {3, 4}}; // int * p = b; int * p = b[0]; std::cout << *(p) << '\n'; int * c = new int[3]; c[0] = 3; std::cout << c[0] << '\n'; delete [] c; return 0; } */
struct
// struct
#include <iostream>
#include <string.h>
using namespace std;
struct abc{
char name[10];
float volume;
int b;
};
int main(int argc, char const *argv[]){
abc ps;
ps.volume = 20.00;
memcpy(ps.name, "hello", 6);
printf("%s\n", ps.name);
abc *pp = new abc;
pp->b = 222;
printf("%d\n", pp->b);
return 0;
}
对象指针写法
// 目录和文件都小写, 重要的事情才大写 // 类的名字首字母大写
#include <iostream> #include <string> using namespace std; class Person { private: int _pid; string _name; int _age; public: int testAbc = 123; int testAbd = 124; Person(); ~Person(); void setpid(int pid); int getpid(); void setname(string name); string getname(); void setage(int age); int getage(); }; Person::Person() { std::cout << "构造函数: " << this->testAbc << '\n'; } Person::~Person() { std::cout << "析构函数: " << this->testAbd << '\n'; } void Person::setpid(int pid) { this->_pid = pid; // this 表示当前对象下的_pid } int Person::getpid() { return this->_pid; } void Person::setname(string name) { this->_name = name; } string Person::getname() { return _name; } void Person::setage(int age) { this->_age = age; } int Person::getage() { return _age; } int main() { // 锦绣城, 双滦区 2区观鱼园 // -----普通方式----- // /* Person per; per.setpid(1); per.setname("tom"); per.setage(20); int pid = per.getpid(); string name = per.getname(); int age = per.getage(); std::cout << "pid: " << pid << " "; std::cout << "name: " << name<< " "; std::cout << "age: " << age << '\n'; */ // -----指针方式-----// Person *per = new Person(); per->setpid(1); per->setname("Baker"); per->setage(20); delete per; return 0; }
出处:http://www.cnblogs.com/renfanzi/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。