C语言-数组指针

sizeof()

char str1[] = {'a', 'b', 'c', 'd', 'e'};
char str2[] = "abcde";
char *str3 = "abcde";
char str4[][80]={"计算机应用基础","C语言","C++程序设计","数据结构"};
sizeof(str1) == 5;//数组,5个元素
sizeof(str2) == 6;//C语言字符串类型以'\0'结尾
sizeof(str3) == 4;//指针类型,占一个字大小
sizeof(str4) == 320;
sizeof(str4[0]) == 80;

strlen()

strlen()是C语言标准库的一个函数,包含在<string.h>头文件中,可以计算string类型所包含的字符个数。

因为设计是为string类型使用,而string类型均以‘\0’结尾,所以该函数的实现为遍历stirng,直至遇到‘\0’返回

char arrayA[] = {'a','b','c','\0','d','e'};
char arrayB[] = {'a','b','c','d','e'};
char arrayC[6] = {'a','b','c','d','e'};
char *str = "abcde";
strlen(arrayA) == 3;//遇到'\0'返回
strlen(arrayB);//不存在'\0'结束符,结果未知
strlen(arrayC) == 5;//指定了数组长度且有剩余空间,数组多余地方补'\0'
strlen(str) == 5;

字符数组和字符指针

char str[] = "hello";
char *str2 = "hello";

str[0] = 'a';//合法,数组内容在栈空间,编译时分配
str2[0]= 'a';//不合法,指针指向字符串常量,字符串常量在静态数据区域
char str1[] = "abc";
char str2[] = "abc";

const char str3[] = "abc";
const char str4[] = "abc";

const char *str5 = "abc";
const char *str6 = "abc";

char *str7 = "abc";
char *str8 = "abc";

cout << ( str1 == str2 ) << endl;
cout << ( str3 == str4 ) << endl;
cout << ( str5 == str6 ) << endl;
cout << ( str7 == str8 ) << endl;
//0 0 1 1

栈空间的数据在变量离开作用域时会被销毁,静态数据区域的数据在程序执行结束时销毁

谨慎值传参

普通值传参:

  • 函数使用的是值的副本,修改该副本不影响原值
  • 改进:将指向值的指针作为参数,通过指针使用该值

指针值传参:

  • 传递指针给函数,但并不是使用指针指向的值,而是将指针当值使用,则对指针对象的修改不影响原指针
  • 改进:将指向指针的指针作为参数,通过二次指针使用指针

const限定符与指针

顶层const:限定指针

底层const:限定指针指向对象

const char *p;//p为指针,指向对象的类型是const char,底层const
char *const p;//p为const指针,指向对象的类型是char,顶层const
const char *const p;//p为const指针,指向对象的类型是const char

const char* *p;//p为指针,指向const char*类型,p非const,(*p)非const, (**p)为const
const char* const *p;//p为指针,指向const char*类型,p非const,(*p)为const, (**p)为const
const char* const *const p;//p为const指针,指向const char*类型,p为const,(*p)为const, (**p)为const

解引用符(*运算符)和递增运算符

注意:

  • 后置递增/递减优先级 > 前置递增/递减优先级 = 解引用优先级
  • 三者均为右结合
  • 后置递增/递减返回值是原对象
int int a[5]={1, 2, 3, 4, 5};
int *p = a;

//先解引用,再对p自增
cout << *p++;//1
cout << (*p++);//1
//p先解引用,对解引用后的值自增
cout << ++*p;//2
cout << (++*p);//2
//先解引用,再对p指向的对象进行自增
cout << (*p)++;//1
cout << ((*p)++);//2
//p先自增,自增后的值再解引用
cout << *++p;//2
cout <<(*++p)//2