指针数组
char *arr4[]= {"hello","world"}; //Eindimensionales Array aus Zeigern
相当于:
const char *anonymous1="hello";
const char *anonymous2="World";
char *arr5[2] = {anonymous1,anonymous2};
printf("%c %s",arr5[1][4],arr5[0]);
数组指针
定义 int (*p)[n];
()优先级高,首先说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n,也可以说是p的步长。也就是说执行p+1时,p要跨过n个整型数据的长度。
如要将二维数组赋给一指针,应这样赋值:
int a[3][4];
int (*p)[4]; //该语句是定义一个数组指针,指向含4个元素的一维数组。
p=a; //将该二维数组的首地址赋给p,也就是a[0]或&a[0][0]
p++; //该语句执行过后,也就是p=p+1;p跨过行a[0][]指向了行a[1][]
char str[2][6] = {"hello","world"};
char (*str2)[6];
str2 = str;
printf("%s", *++str2); // world
所以数组指针也称指向一维数组的指针,亦称行指针。
三维数组
Char arr3[5][4][3];
Char *ptr1=&arr3[1][3][0]; //Zeiger auf Array arr3[1][3][0];
*ptr1 //entspricht arr3[1][3][0]
Ptr1[1]; //entspricht arr3[1][3][1];
*(ptr1‐1); //entspricht arr3[1][2][2];
Neuer Abschnitt 1 Seite 3 Char (*ptr2)=arr3[3][1]; //Zeiger auf Array arr3[3][1][0..2]
Ptr2[2] //entspricht arr3[3][1][2]
*(ptr2+2)
Char (*ptr3)[3]= arr3[2]; //Zeiger auf Array arr3[2][0..3][0..2]
Ptr3[3][1] //entspricht arr3[2][3][1]
char ptr4[4][3] = arr3[2]; //???
char ptr5[ ] [3] = arr3[2]; //???
char (*ptr6)[4][3] = arr3; //Zeiger auf Array arr3[0..4][0..3][0..2]
Ptr4[4][3][2] //entspricht arr3[0][4][3][2]
预留空间
数组的存储空间也可以预留为堆空间。
short (*ptr1)[3][2]=malloc(sizeof(short)*2*3*4711);
ptr1[4700][2][1]=11;
为了将数组每一位都初始化为0,推荐使用calloc。
short (*ptr2)[3][2]=calloc(sizeof(sort),2*3*4711);
数组初始化
像结构体那样用大括号初始化数组
int arr1[3] = {1, 2, 3};
int arr2[] = {1, 2, 3};//在这里,我们arr[3]里边的数字可以不用写;
int arr3[3] = {1, 2};//也是可以的,只是把最后一个数初始化为0了而已
long long vector1[4]={1LL,2LL,3LL,4LL};
long long vector2[] ={7,8,9,10};
字符串数组可以用引号初始化,最后一位默认为’\0’。
char string1[5]="4711";
char arr1a[4]={1,2,3,4}; //OK
char arr1b[4]={1,2,3,4,5}; //KO compiler‐fehler
char arr1c[4]={1,2,3}; //OK, Fehlende Elemente werden auf 0 gesetzt
char arr1d[] ={1,2,3,4}; //OK, Dimension ergibt sich aus der Anzahl der Initialisierungslemente
char arr1e[100]={0}; //OK, Fehlende Elemente werden auf 0 gesetzt
char arr2a[6]="hello"; //OK
char arr2b[5]="hello"; //OK, aber die Speicher overflow
char arr2c[4]="hello"; //OK, aber die Speicher overflow
char arr2d[8]="hello"; //OK, aber compiler fuellt arr[6] und arr[7] mit '\0'
char arr2e[] ="hello" "world" "ich" //OK, entspicht char arr2e[14] = "helloworldich"
int arr3f[6]="hello"; //KO
char arr4a[4][3] = { {1,2,3},{4,5,6},{7,8,9},{10,11,12} }; //OK
char arr4b[4][3] = { 1,2,3,4,5,6,7,8,9,10,11,12 }; //OK,
char arr4c[3][10] = { "hallo","du","da" }; //OK
在C99中允许用户在数组初始化时像结构体一样给具体某一位赋值:
char arr5[20] = {[0]='a', [8]=33,34,[3]=35,36, [10 ... 12]=3 };
char arr6[4][3]= {[1][1]=7};
将数组用0填充
对于长度为常量的数组可以通过Trick = {0} 的方式给每个数组元素赋值为0. 但是对于其他数组,则可以采用memset赋0.
char arr7[5][4];
memset(arr7,0,sizeof(arr7));
float arr8[8][9];
memset(arr8,1,sizeof(float)*8*9); //每个数组元素都是0x01 0x01 0x01 0x01 构成的浮点数
数组的相等判断
数组名字实际上是这个数组的指针,因此直接比较数组实际上比较的是地址
char arr1[4],arr2[4];
if(arr1 == arr2) //Für Compiler OK, jedoch erfolgt hier ein Pointervergleich
想要真正比较数组比较必须手动编写for循环或者使用函数memcmp():
For(int lauf=0;lauf<4;lauf++) if(arr1[lauf]!=arr2[lauf]) break;
if(memcmp(arr1,arr2,sizeof(arr1)) == 0)
数组的拷贝
直接使用arr2 = arr1将只是复制arr1的地址
int arr[10] = {[1] = 2};
int arr2[10];
// arr2 = arr; //KO
int *arr3;
arr3 = arr; //OK
使用memcpy(char *dst, char *src, sizeof(src));
memcpy(arr2,arr1,sizeof(arr1));
数组作为函数形参
函数要传递数组时,有很多方法来定义:
//方法一
#include<stdio.h>
void fun(int b[][3])
{
b[1][2]=3;
}
void main()
{
int a[3][3]={0};
fun(a);
printf("%d\t%d\n",b[1][2],b[0][0]); //3 0
}
//方法二
#include<stdio.h>
void fun(int **a)
{
a[1][3]=3;
printf("%d\t%d\n",a[1][3],a[0][0]);
}
void main()
{
int *p[3],b[3][3]={0};
p[0]=b[0];
p[1]=b[1];
p[2]=b[2];
fun(p);
}
注:
- 在主函数中定义int *p;p[0] = 0;这是不允许的。
- 在子函数中定义了一个数组变量,对变量赋值,离开函数体之后这个变量及其内容将清除,但是字符串常量将保留在内存的字符串常量区不会被清楚:
char *function(void){
// char str[11] = "helloworld"; // 无法将值return出去
char *str = "helloworld"; // 可以将值return出去
return str;
}
int main(int argc, char const *argv[])
{
char *arr;
arr = function();
printf("%s", arr);
}