C++ Primer Plus 第四章

sizeof作用于数组名,得到整个数组的字节数,sizeof作用于数组元素,则得到的将是元素的长度(字节数)

对于数值型元素,如果只对数组的一部分初始化,则编译器将把其他元素设置为0

C-风格字符串有一个特殊性质,以空字符结尾(\0,ASCII码值为0)

任何两个由空白分隔的字符串常量都将自动合并为一个

ex:
char array[10] = {'1','2','3'};  
string s = "123";
cout << strlen(array) << endl;     // 3
cout << sizeof(array) << endl;     // 10
cout << s.length() << endl;          // 3
cout << sizeof(s)  << endl;          // 28(?)

char bird[10] = "Mr. Cheeps",用引号括起的字符串隐式的包括结尾的空字符,若只初始化一部分,则余下元素都被填为\0
如果有 char array[10] = "1234567890" vs环境下会直接报错

strlen()与sizeof()的区别
sizeof返回整个数组的长度,strlen则一直计算到遇到第一个\0为止

cin使用空白(空格,制表符,换行符)来界定字符串的界,会消费掉空白,但不会保存

cin.getline(char* s, streamsize n );面向行的输入, 使用换行符号来确定界,会消费掉换行,但不会保存
*s 存储输入行的字符数组
n  要存入的字符数,如果参数为20,则函数最多读取19个字符,因为要加上\0
ps:cin<< 不能读取空白符号

cin.get()
1 cin.get() 读取下一个字符,包含空白符
2 cin.get(char* s, streamsize n) 与cin.getline类似,但还不会消费掉换行,而将其保存在输入缓存中

ex:用 cin.getline cin.get,直接输入回车,则cin.get会等待下一个输入;用cin.get(char* s, streamsize n) cin.get,则cin.get会读到输入缓存中的空格,以'\0'表示

char charr[20];
string str;
cin.getline(charr, 20);
getline(cin, str);          //note:string会自己调整大小

ps:
char * strcpy ( char * destination, const char * source );
char * strncpy ( char * destination, const char * source, size_t num );     //如果满了,则不会自动添加\0
char * strcat ( char * destination, const char * source );
char * strncat ( char * destination, const char * source, size_t num );

//other-内存重叠!
void * memcpy ( void * destination, const void * source, size_t num );
void * memmove ( void * destination, const void * source, size_t num );
const void * memchr ( const void * ptr, int value, size_t num );
int memcmp ( const void * ptr1, const void * ptr2, size_t num );


//================
struct inflatable
{
     char name[20];
     float volume;
     double price;
};
inflatable hat;     //C中:struct inflatable hat;
inflatable hat = {"111", 1.2, 29.99}
inflatable guests[2] =
     {
          {"Bambi",    0.5,  21.99},
          {"Godzilla", 2000, 565.5}
     }
结构体sizeof,最大长度的成员长度M(结构体的长度一定是该成员的整数倍)
    
一个空的结构体
struct torgle_register{}; torgle_register a; sizeof(a) = 1
“空结构体”(不含数据成员)的大小不为0,而是1。试想一个“不占空间”的变量如何被取地址、两个不同的“空结构体”变量又如何得以区分呢于是,“空结构体”变量也得被存储,这样编译器也就只能为其分配一个字节的空间用于占位了。    
静态变量存放在全局数据区内,而sizeof计算栈中分配的空间的大小,故不计算在内,
    
位字段
struct torgle_register
{
     unsigned int SN:4;      //只会用到4位;例如 如果有 unsigned int SN:2 则只能存储0~3的数
     unsigned int: 4;     //4位占位,用于提供间距
     bool goodIn: 1;
     bool goodOut: 1;
};
一个位域必须存储在同一个字节中,不能跨两个字节。如一个字节所剩空间不够存放另一位域时,应从下一单元起存放该位域。也可以有意使某位域从下一单元开始

共用体可以存储也只能存储char,short,int,long,double或数组
union one4all
{
     int int_val;
     long long_val;
     double double_val;
};
共用体的sizeof为最大成员的大小
共用体最多同时只能以一种形态存在
struct widgt
{
     int type
     union id
     {
          long id_num;
          char id_char[20];
     } id_var;
}
widgt prize; prize.id_val.id_num

匿名共用体
struct widgt
{
     int type
     union
     {
          long id_num;
          char id_char[20];
     }
}
widgt prize; prize.id_num

字节对齐的细节和编译器实现相关,但一般而言,满足三个准则:
1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);
3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)。
//还需要仔细看

枚举
enum spectrum {red, orange, yellow, green, blue, violet, indigo, ultraviolet}
通常,按顺序将枚举值赋值为整数值,从0开始
枚举没有算术运算
枚举是整型,可以提升为int值,但是int值不能自动转换为枚举
band = orange + red是非法的,这是因为orange + red是合法的,因为枚举将会转换为int值进行运算得到3,但是 band = 3是非法的
band = spectrum(3)         //合法的        
band = spectrum(40003) //合法的,但结果不确定        

枚举的值
enum bigstep{first, second = 100, third} ---> (1,100,101) 没有初始化的枚举量的值比其前面的枚举量大1
允许创建多个值相等的枚举量
enum {zero, null = 0, one , numero_uno = 1}; ----> (0,0,1,1)

枚举值的最大值:大于枚举最大值的,最小的2的幂-1

地址操作符(&) 解引用操作符(*)

使用指针的金科玉律:将指针初始化为一个确定的,适当的地址

int *pt = 0xB8000000 //C语言可以 C++报错
int *pt = (int *)0xB000000 //现在0xB000000被初始化为一个int型指针的地址

使用new来分配内存,使用delete来释放内存
int i = new int; delete i;

int j = 1;
int *i = &j;
delete i;          //运行时出错,只能delete用new分配的内存

delete一个已经释放的内存块的结果是未知的

int *psome = new int[10];
delete [] psome;

new/delete规则:
不要使用delete来释放不是new分配的内存
不要使用delete释放用一个内存块两次
如果使用new[] 为数组分配内存, 则用delete[] 来释放
对空指针delete是安全的

指针,数组名的区别
不能修改数组名的值,但可以修改指针的值
sizeof作用结果不同

在多数情况下,C++将数组名解释为数组第1个元素的地址

指针变量+1后,其增加值为指向的类型占用的字节数

stacks[1] => * {stacks + 1}

char[] char* 在打印时,会一直打印到遇到\0为止
note:在cout和多数C++表达式中,char数组名,指向char的指针,引号括起的字符串常量都被解释为字符串中第一个字符的地址

一般来说,编译器在内存中留出一些空间,以存储程序源代码中所有用引号括起的字符串<--->字符串字面值是常量,这就是为什么要  const char *bird = "wren"

C++ 变量存储类型
自动存储:在函数活动时存在,在函数结束时消亡     //被放在栈上?
静态存储(static):整个程序周期都存在,第9章详细介绍
动态存储:new/delete(一个内存池,自由存储空间free stroe)

内存泄露:用了new,却没有用delete

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值