[C-Sprachgrundlage 11 – Zeiger (2)]


Vorwort

Dieser Artikel setzt den vorherigen Inhalt fort und lernt weiterhin Wissenspunkte im Zusammenhang mit Zeigern kennen.


4. Zeigerbetrieb

  • Zeiger ± ganze Zahl
  • Zeiger - Zeiger
  • Relationale Operationen auf Zeigern

4.1 Zeiger ± Ganzzahl

#define VALUE 5
int main()
{
    
    
	float values[VALUE];
	float *vp;
	//指针+-指针,关系运算
	for (vp = &values[0]; vp < &values[VALUE];)
	{
    
    
		*vp++ = 0;//通过这样完成初始化
	}
	for (int i = 0; i < VALUE; i++)
	{
    
    
		printf("%d ", values[i]);
	}
	return 0;
}

Bildbeschreibung hier einfügen

4.2 Zeiger-Zeiger

int main()
{
    
    
	int arr[10] = {
    
     0 };
	printf("%d\n", &arr[9] - &arr[0]);//得到元素的个数
	printf("%d\n", sizeof(arr)/sizeof(arr[0]));//计算元素个数
	int* p0 = &arr[0];
	int* p9 = &arr[9];
	printf("%d\n", (p9 - p0));//得到元素的个数
	return 0;
}

Durch Subtrahieren der Adressen des ersten und letzten Elements des Arrays erhält man die Anzahl der Elemente im Array.

-int* gibt an, dass die Adresse, auf die der Zeiger zeigt, der gespeicherte Datentyp eine ganze Zahl ist und 4 Bytes belegt

  • Die Adresse des Array-Elements +1 soll die Adresse des nächsten Elements finden, und es wird 4 Bytes verschoben
    Bildbeschreibung hier einfügen
    . Dieses Phänomen wird beim Debuggen deutlicher beobachtet. Jedes Element des int-Arrays belegt vier Bytes:
  • &arr[0]: 0x005cf7f8
  • &arr[0]+1: 0x005cf7fc, die Adresse wird um 1 Bit verschoben, d. h. der int*-Zeiger wird um 1 Bit verschoben, und die Bytes werden um 4 erhöht.
    Bildbeschreibung hier einfügen
    Voraussetzung: Beide Zeiger müssen auf das gleiche Leerzeichen zeigen :
char ch[5];
int arr[6];
%arr[4]-&ch[3];//错误的

Im vorherigen Artikel wurde die Methode der Zeichenfolgenlänge auf zwei Arten eingeführt:

  • Kreislauf
  • Rekursion

Die dritte Methode wird hier eingeführt, Zeiger

int mylen(char* pa)//传参是数组首元素的地址
{
    
    
	char* p = pa;//首元素地址
	while (*pa)//元素不是‘0’
	{
    
    
		pa++;//通过地址访问字符串
	}
	//结尾字符0的地址减首元素地址
	return pa - p;//指针相减是元素的个数
}
int main()
{
    
    
	char arr[] = "abcdef";
	int len = mylen(arr);
	printf("%d", len);
	return 0;
}

4.3 Relationale Operationen auf Zeigern

Der Standard besagt: Ein Zeiger auf ein Array-Element darf mit einem Zeiger auf einen Speicherplatz nach dem letzten Element des Arrays verglichen werden, aber ein Vergleich mit einem
Zeiger auf einen Speicherplatz vor dem ersten Element ist nicht zulässig

int main()
{
    
    
	//
	for (vp = &values[5]; vp > &values[0];)
	{
    
    
		*--vp = 0;
	}
	for (vp = &values[5-1]; vp >= &values[0];vp--)//不允许
	//地址会指向首元素前面的地址,这是不允许的
	{
    
    
		*vp = 0;
	}
	return 0;
}

5. Zeiger und Arrays

int main()
{
    
    
	int arr[10] = {
    
    1,2,3,4,5,6,7,8,9,0};
	printf("%p\n", arr);
	printf("%p\n", &arr[0]);
	int *p = arr;//p存放的是数组首元素的地址
	return 0;
}

Der Array-Name ist derselbe wie die Adresse des ersten Elements des Arrays. Der Array-Name repräsentiert die Adresse des ersten Elements des Arrays. (Bis auf 2 Fälle werden die Artikel der Array-Serie ausführlich vorgestellt)
Bildbeschreibung hier einfügen
Da der Array-Name in einem Zeiger als Adresse gespeichert werden kann, ist es uns möglich, den Zeiger zu verwenden, um auf einen zuzugreifen

int main()
{
    
    
	int arr[] = {
    
    1,2,3,4,5,6,7,8,9,0};
	int *p = arr; //指针存放数组首元素的地址
	int sz = sizeof(arr)/sizeof(arr[0]);
	for(int i=0; i<sz; i++)
	{
    
    
		printf("&arr[%d] = %p <====> p+%d = %p\n", i, &arr[i], i, p+i);
	}
	return 0;
}

Bildbeschreibung hier einfügen
Beachten Sie die obige Abbildung, also berechnet p+i tatsächlich die Adresse des Elements, dessen Index i im Array arr ist. Dann können Sie direkt über den Zeiger auf das Array zugreifen:

int main()
{
    
    
	int arr[10] = {
    
     1,2,3,4,5,6,7,8,9,10 };
	int* p = arr;
	int sz = sizeof(arr) / sizeof(arr[0]);
	for (int i = 0; i < sz; i++)
	{
    
    
		printf("%d ",*(p + i));
	}
	printf("\n");
	for (int i = 0; i < sz; i++)
	{
    
    
		printf("%d ", *(p++));
	}
	printf("\n");
	for (int i = 0; i < sz; i++)
	{
    
    
		printf("%d ", arr[i]);
	}
	return 0;
}

Bildbeschreibung hier einfügen

6. Sekundärzeiger

Eine Zeigervariable ist auch eine Variable, und eine Variable hat eine Adresse Wo wird die Adresse der Zeigervariable gespeichert? Dies ist der sekundäre Zeiger

int main()
{
    
    
	int a = 10;
	int* pa = &a;
	int** ppa = &pa;
	return 0;
}
  • Die Adresse von a wird im Zeiger pa gespeichert, der ein Zeiger der ersten Ebene ist
  • Die Adresse von pa wird in ppa gespeichert, das ein sekundärer Zeiger ist
    Bildbeschreibung hier einfügen

Die Operationen für sekundäre Zeiger sind:

  • *ppa dereferenziert die Adresse in ppa, um pa zu finden, und *ppa greift tatsächlich auf pa zu.
int b = 20;
*ppa = &b;//等价于 pa = &b;
  • **ppa findet zuerst pa bis *ppa und dereferenziert dann pa: *pa, das findet a
**ppa = 30;
//等价于*pa = 30;
//等价于a = 30;

7. Array von Zeigern

Ist ein Array von Zeigern ein Zeiger oder ein Array?

  • ist ein Array. ist ein Array von Zeigern

In den Artikeln der Array-Reihe wurden Integer-Arrays und Zeichen-Arrays eingeführt:

int arr1[5];//占用20个字节
char arr2[5];//占用5个字节

Bildbeschreibung hier einfügen

7.1 Beispiel 1

Array von Zeigern:

int main()
{
    
    
	int data1[] = {
    
     1,2,3,4,5 };
	int data2[] = {
    
     2,3,4,5,6 };
	int data3[] = {
    
     3,4,5,6,7 };
	//看成二维数组
	int* arr[3] = {
    
     data1,data2,data3 };
	for (int i = 0; i < 3; i++)
	{
    
    
		for (int j = 0; j < 5; j++)
		{
    
    //[]是操作符
			printf("%d ", arr[i][j]);//不需要解引用
		}
		printf("\n");
	}
	   
	return 0;
}

arr3 ist ein Array mit fünf Elementen, jedes Element ist ein ganzzahliger Zeiger, der eine Adresse ist:

  • arr[0], das Element data1, ist eine Zeigervariable und selbst der Arrayname eines eindimensionalen Arrays { 1,2,3,4,5 }, das die Adresse des ersten Elements darstellt
  • arr[1], das Element data2, ist eine Zeigervariable, die auch der Array-Name eines eindimensionalen Arrays { 2,3,4,5,6 } ist, das die Adresse des ersten Elements darstellt
  • arr[2], das Element data3, ist eine Zeigervariable und selbst der Array-Name des eindimensionalen Arrays { 3,4,5,6,7 }, das die Adresse des ersten Elements darstellt

Bildbeschreibung hier einfügen
Bildbeschreibung hier einfügen
Es kann auch durch Debuggen gefunden werden:

  • Das erste Element des Zeigerarrays, data, ist eine Zeigervariable und die Adresse des ersten Elements eines eindimensionalen Arrays.
  • Auf Elemente im Array kann über den Array-Namen + i zugegriffen werden
  • Ein Array von Zeigern kann als zweidimensionales Array betrachtet werden
arr[0]=data1;//指针数组首元素data,是指针变量,也是一维数组首元素的地址
arr[0][0]=data1[0];//看成一维数组
arr[0][1]=data1[1];
arr[0][2]=data1[2];
arr[0][3]=data1[3];
arr[0][4]=data1[4];

Bildbeschreibung hier einfügen
Das Druckergebnis ist in der folgenden Abbildung dargestellt:
Bildbeschreibung hier einfügen
Der Code wird mit folgendem Effekt ersetzt und aus der Perspektive der Adress-Dereferenzierung geschrieben:

int main()
{
    
    
	int data1[] = {
    
     1,2,3,4,5 };
	int data2[] = {
    
     2,3,4,5,6 };
	int data3[] = {
    
     3,4,5,6,7 };
	//看成二维数组
	int* arr[3] = {
    
     data1,data2,data3 };
	for (int i = 0; i < 3; i++)
	{
    
    
		for (int j = 0; j < 5; j++)
		{
    
    
			printf("%d ", *(arr[i]+j));//地址访问解引用
		}
		printf("\n");
	}   
	return 0;
}

Bildbeschreibung hier einfügen

7.2 Beispiel 2

Die Elemente im Pointer-Array sind Pointer-Variablen, also die Adresse

int main()
{
    
    
	int a = 10;
	int b = 11;
	int c = 12;
	int d = 13;
	int e = 14;
	int* arr[5] = {
    
     &a,&b,&c,&d,&e };//指针数组存放的元素是指针变量,就是地址
	for (int  i = 0; i < 5; i++)
	{
    
    
		printf("%d ", *(arr[i]));//地址解引用
	}
	return 0;
}

Bildbeschreibung hier einfügen


Zusammenfassen

Dieser Artikel setzt sich mit dem Erlernen der Wissenspunkte im Zusammenhang mit Zeigern fort.Zeiger sind der wichtigste Teil der Sprache C. In der Grundstufe endet das Erlernen von Zeigern.

Der nächste Artikel wird die Wissenspunkte von Strukturen lernen.

Ich denke du magst

Origin blog.csdn.net/taibudong1991/article/details/123963476
Empfohlen
Rangfolge