C++杂记之new初体验(pointer, structures)

一、指针操作
1、首先我们得明确 *时取值操作 &是取址操作

2、定义指针时需要指定地址或者开辟新的内存空间也就是用new来进行开辟

#相对于c语言的malloc函数,c++有一个更cool的写法就是
int *pointer = new int; //是不是觉得very cool
double *pointer = new double;

int *pointer = 122;  #是不行的
//注意取值和取址符号
int a = 3;
int *pointer;
pointer = a; //出错,因为pointer指向的是地址
*pointer = a;//ok,因为*pointer是取值操作哦

3、相应的有(new)那就应该有delete operate 【在我的C++杂记中automatic、static、dynamic中有提到memory leaks】

//此时的用法可谓是相当无脑
int *pointer = new int;
delete pointer;
//无论我们是操作什么,delete都是一个很重要的操作,可以防止内存泄漏,例如文件操作,有open 也要有相应的close operate

4、创建指针数组 (static binding and dynamic binding 相对于dynamic binding 称为dynamic arrary 【But with new , you can create an array during runtime if you need it and skip creating the array if you don’t need it. Or you
can select an array size after the program is running.This is called dynamic binding, meaning
that the array is created while the program is running. Such an array is called a dynamic
array.】)(简单来讲就是数组是static binding是在compile 时allocated ,而指针数组通过new来进行开辟,是在runtime进行allocated)

int *arr = new int[4]; //定义指针数组
delete [] arr;//The presence of the brackets tells the program that it should free the whole array, not
just the element pointed to by the pointer.(这个[] 代表的是释放整个数组,而不是单纯的元素)
//Note:
int * pt = new int;
short * ps = new short [500];
delete [] pt;  // effect is undefined, don't do it
delete ps;     // effect is undefined, don't do it
In short, you should observe these rules when you use new and delete :
n Don’t use delete to free memory that new didn’t allocate.
n Don’t use delete to free the same block of memory twice in succession.
n Use delete [] if you used new [] to allocate an array.
n Use delete (no brackets) if you used new to allocate a single entity.
n It’s safe to apply delete to the null pointer (nothing happens).
总的来说就是不要用delete [] 来释放不是数组的指针,也不要不用delete[] 来释放指针数组

5、指针的操作

//与数组并无异议的操作-用下表进行取值和赋值操作
double * p3 = new double [3];
 p3[0] = 0.2;                  
 p3[1] = 0.5;
 p3[2] = 0.8;
 p3 = p3 + 1; // okay for pointers, wrong for array names

6、pointers arrarys and pointer arithmetic (计算)

double wages[3] = {10000.0, 20000.0, 30000.0};
short stacks[3] = {3, 2, 1};
// Here are two ways to get the address of an array
double * pw = wages;     // name of an array = address
double * pw = &wages[0]; // or use address operator

// with array element
cout << "pw = " << pw << ", *pw = " << *pw << endl;  #10000.0
pw = pw + 1;  //就是对pw进行地址往下加一,指向20000.0的地址
cout << "add 1 to the pw pointer:\n";
cout << "pw = " << pw << ", *pw = " << *pw << "\n\n";  #20000.0

*(pw+ 1) //上面我们说的*是取值操作,那就是我们的pw先地址往下加1,指向30000.0的地址,取值出来,也就是cout 出口来应该是30000.0 
//(可以自行验证一下,大家也可以用地址来验证一下,看每次取得地址是不是与上一个都加上8,因为double 是8 bytes)

7、pointer and string

char animal[20] = "bear";   // animal holds bear
const char * bird = "wren"; // bird holds address of string
char * ps;                  // uninitialized
cout << animal << " and ";  // display bear
cout << bird << "\n";       // display wren

ps = naimal;//得出的两个地址是一样得
//用strcpy复制得得出的地址是不一样得
ps = new char[strlen(animal) + 1];  // 为了有一个复制可以存储的载体,沃恩需要新开辟与原字符+1的空间,为什么要+1【自己思考一下】get new storage
strcpy(ps, animal);         // copy string to new storage
//既然cout << bird 出现的是值,那怎么取得地址呢,可以用(int *)bird来进行取得

8、strcpy() or strncpy()

char food[20];
strcpy(food, "a picnic basket filled with many goodies"); //我们定义的长度与要复制的长度不一致
//可以用strncpy 有第三个参数,可以指定要复制的字符个数
strncpy(food, "a picnic basket filled with many goodies", 19);
food[19] = '\0';

9、有一个好玩的案例
例如,我们需要100次输入有个不定长(不超过80)的字符,如果我们用char 数组来进行操作,是不是需要定义100个char input[80]的数组。那我们试想一下,可不可以用指针来进行操作,用一个char[80],用来接收输入,到时开辟与输入字符等长的指针数组来存放,然后char[80]进行reuse,以此来减少内存的开销呢???

#include <iostream>
#include <cstring>      // or string.husing 
namespace std;
// function prototype
char * getname(void);   
int main(){
char * name;        
// create pointer but no storage
name = getname();   
// assign address of string to name
cout << name << " at " << (int *) name << "\n";
delete [] name;     // memory freed
name = getname();   // reuse freed memory
cout << name << " at " << (int *) name << "\n";
delete [] name;     // memory freed again
return 0;
}
//getname函数
char * getname()        // return pointer to new string
{
char temp[80];      // temporary storage
cout << "Enter last name: ";
cin >> temp;
char * pn = new char[strlen(temp) + 1]; //输入的字符有几个我们就开辟几个空间即可啦
strcpy(pn, temp);   // copy string into smaller space
return pn;          // temp lost when function ends
}

二、结构体操作(我们在数据结构中的树,链表中经常用到 【leetcode】)
dynamic structure 与 common structures的区别:
When you create a dynamic structure, you can’t use the dot membership operator with the structure name because the structure has no name.All you have is its address. C++ provides an operator just for this situation: the
arrow membership operator ( -> ).(你不能用 . 操作来获取成员变量了,而需要用->来进行操作哦)

1、结构体定义,实例化,访问

扫描二维码关注公众号,回复: 5598428 查看本文章
struct inflatable   // structure definition
{
char name[20];
float volume;
double price;
};

//实例化,有没有等多java 和 c# 的风格,舒服呀
inflatable * ps = new inflatable; // allot memory for structure
cout << "Enter name of inflatable item: ";
cin.get(ps->name, 20);            // method 1 for member access
cout << "Enter volume in cubic feet: ";
cin >> (*ps).volume;              // method 2 for member access
cout << "Enter price: $";
cin >> ps->price;
cout << "Name: " << (*ps).name << endl;              // method 2
cout << "Volume: " << ps->volume << " cubic feet\n"; // method 1
cout << "Price: $" << ps->price << endl;             // method 1
delete ps;                        // 到哪里都是一个好习惯呀

猜你喜欢

转载自blog.csdn.net/qq_37982109/article/details/88686728