数组
数组:具有相同类型的数据的有序的集合。
- 1、相同类型
- 2、有序(数据在内存上是连续的。)
- 3、集合(容量)
一维数组
类型 数组名[容量] = {初始值};
数组名就是首元素的地址
初始化:
int ary[5]={1,2,3,4,5}; //ary[0]=>1;ary[1]=>2...ary[4]=>5
int ary[]={1,2,3,4,5,6}; //初始化后容量不能改变。
int ary[5]={0}; //缺省 int ary[5]={0,0,0,0,0};
int ary[5]; //right
int ary[]; //false
int i=5;
int ary[i]; //false//容量不能使用变量。
赋值:
ary[0]=10; //right
ary[5]={1,2,3,4,5};//false//除了初始化的时候,数组不允许整体
二维数组
初始化:
顺序初始化
int arr[2][3] = {1,2,3,4,5,6};
按行初始化
int arr[2][3] = {{1,2},{3,4},{5,6}};
指针
定义: 指针是某块内存空间的地址,是一个常量,不可改变
指针变量:
就是我们通常所说的“指针”,是个变量,可以改变。
指针变量的值是内存的地址。
指针运算符:
& 取地址符。取一个数值在内存中的地址。
* 取值符。取一个地址上的数值。
指针是如何定义的:
//数据类型 * 变量名=初始化
int* p = NULL; //*表示后面的p为整型指针
*p; //*表示取指针p上的值
通用地址:
void* v = NULL;
指针和一维数组的关系:
int arr[5]={1,2,3,4,5};
//arr:首元素的地址,代表了数组。
int* p = NULL;
p = arr;
指针常量:
指针所指向的空间不可修改,该指针可以指向别的空间
int const *p;
const int *p;
常量指针:
指针是一个常量,一旦初始化化不可以指向别的空间,但所指向空间中的内容可以修改
int* const p;
常量指针常量:
指针所指向的空间和空间中的内容都不可修改
const int* const p
函数指针:
函数指针赋值
int function(int a, int b)
{
//执行代码
}
int main(void)
{
int (*FP)(int, int) = function;
int (*FP)(int, int) = &function;
}
两种方法都可以,C/C++里面的数组名字会退化为指针,所以数组名a实际指的是数组的第一个元素的地址。而数组名作为指针来讲有特殊性,它正在它所指向的内存区域中,&a的值和a的数值是相同的,但是类型和意义不同。而指针的加法操作和指向的数据类型密切相关。
函数指针调用
int function(int a, int b)
{
//执行代码
}
int main(void)
{
int (*FP)(int, int);
FP= function; //第一种赋值方法
// FP = &function; //第二种赋值方法
FP(1,2); //第一种调用方法
// (*FP)(1,2); //第二种调用方法
}
两种函数指针的调用方式也相同,与上面同理。
typedef函数指针用法
#include <string.h>
int ret(int a){return a;}
typedef int (*fuc)(int);
fuc function1;
fuc function2;
int main(int argc, char** argv[]){
function1 = ret;
function2 = &ret;
int a = (*function1)(1);
int b = function2(2);
printf("%d %d\n", a, b);
return 0;
}
typedef的功能是定义新的类型。第一句就是定义了一种Pfunc的类型,并定义这种类型为指向某种函数的指针,这种函数以一个int为参数并返回char类型。后面就可以像使用int,char一样使用func。
指针函数:
返回值是指针的函数,定义如下:
int* func(int)
指针数组:
数组中的元素是指针
int *a[5];//成员为指针的数组
数组指针:
int a[3][4];
int (*p)[4]; //代表有四个元素的数组
首先()优先级高,它是一个指针,指向一个整型数组。n为数组长度,当p+1需要跨越n个整型数据的长度,通常用来表示二维数组及二维数组的参数传递。
字符串
//strlen
int myStrlen(char* str)
{
assert(str);
int i = 0;
while(*(str + i) != '\0')
i++;
return i;
}
//strcpy
char* myStrcpy(char* str1, const char* str2)
{
assert(str1 || str2);
char* p = str1;
while(*str2) *p++ = *str2++;
*(p + +) = '\0';
return str1;
}
//strncpy
char* myStrncpy(char* str1, const char* str2, int n)
{
assert(str1 || str2);
char* p = str1;
while(*str2 && n > 0){
*p++ = *str2++;
n--;
}
*(p + +) = '\0';
return str1;
}
//strcmp
int myStrcmp(const char* str1, const char* str2)
{
assert(str1 || str2);
while(*str1 || *str2){
if(*str1 == *str2){
str1++;
str2++;
}
else{
return *str1 - *str2;
}
}
return 0;
}
strcat(连接两字符串)
char* myStrcat(char* str1, const char* str2)
{
assert(str1 || str2);
char* p = str1;
while(*str1) str1++;
while(*str2) *(str1 + +) = *(str2 + +);
return p;
}
strstr()
判断字符串str2是否是str1的子串,如果是返回str2在str1中出现的首地址,如果不是返回NULL
char* myStrstr(const char* haystack, const char* needle)
{
assert(haystack || needle);
int L1 = strlen(haystack);
int L2 = strlen(needle);
int i = 0, j = 0;
while(i < L1 && j < L2){
if(haystack[i] == needle[j]){
i++;
j++;
}else{
i++;
j = 0;
}
if(j >= L2){
return haystack + (i - j)
}
}
}