Cien mil conocimientos fríos del lenguaje C.

Tabla de contenido

1. valor de retorno de printf:

2. escaneo

3. tamaño del valor de retorno

 4. [ ] operador de referencia de subíndice

 5. Sustitución de { } y [ ]

 6. Concatenación de cadenas

 7. Arreglos y nombres de arreglos


1. valor de retorno de printf:

Éxito: devuelve el número de caracteres impresos

Error: devolver EOF, EOF es el final del archivo y la definición de macro es -1

#include <stdio.h>
int main() {
	char str[] = "123456789";
	printf("%d\n", printf("%d\n", printf("%s\n", str)));
	return 0;
}

 El printf más interno imprime "123456789\n", un total de 10 caracteres, y el valor devuelto es 10, que se imprime con el segundo printf, y así sucesivamente.

2. escaneo

Éxito: Devuelve el número de entradas exitosas, que puede ser 0

Error: devolver EOF, EOF es el final del archivo y la definición de macro es -1

#include <stdio.h>
int main() {
	int a = 0, b = 0;
	printf("scanf返回值=%d\n", scanf("%d %d", &a, &b));
	printf("a=%d\nb=%d", a, b);
	return 0;
}

 

 Por lo tanto, es posible escribir código del siguiente tipo:

#include <stdio.h>
int main() {
	int a;
	char arr[10] = { 0 };
	while (scanf("%d %s", &a, arr)==2){
		printf("%d %s\n", a, arr);
	}
	return 0;
}

3. tamaño del valor de retorno

El valor de retorno de sizeof es de tipo size_t, que es un entero sin signo, que representa el tamaño de la memoria ocupada, y la unidad es byte.

 size_t se define en stddef.h según algunos estándares de C/C++. El tipo size_t representa la longitud máxima que puede alcanzar cualquier objeto en C. Es un número entero sin signo. Se define para la comodidad de la portabilidad entre sistemas, y size_t se puede definir de manera diferente en diferentes sistemas. size_t se define como unsigned int en un sistema de 32 bits, es decir, un entero de 32 bits sin signo. Definido como largo sin signo en un sistema de 64 bits, es decir, un entero sin signo de 64 bits. El propósito de size_t es proporcionar una forma portátil de declarar un tamaño consistente con las regiones direccionables de memoria en el sistema.
Se recomienda utilizar %zu para imprimir y, en ocasiones, %u y %lu están disponibles.

#include <stdio.h>
int main() {
	char a[] = "123456789";
	char* p = a;
	printf("%zu", sizeof(p));
	return 0;
}

 

 4. [ ] operador de referencia de subíndice

#include <stdio.h>
int main() {
	char a[] = "123456789";
	printf("%c\n", a[5]);
	printf("%c\n", 5[a]);
	printf("%c\n", *(&a[0] + 5));
	printf("%c\n", "123456789"[5]);
	printf("%c\n", 5["123456789"]);
	printf("%c\n", *("123456789"+5));
	return 0;
}

A primera vista, qué es esta cosa, qué código tan extraño. Primero tienes que averiguar qué significa [ ].

Hay dos formas de definir una cadena:

char* p="123456789"

char a[]="123456789"

Ambos pueden definir cadenas, al generar un carácter en la cadena:

*(p+i);

ai]

Los dos son equivalentes, entonces *(a+i)=a[i]

La definición del operador [ ] se da a continuación:

1. Al definir una matriz, solicite un espacio continuo al compilador.

2. El puntero [ i ] indica que, a partir de la posición actual del puntero, salte hacia atrás i espacio del tamaño del tipo al que apunta el puntero.

3.p[q] es equivalente a *(p+q), si pq no es un puntero, ¡se informará un error!

De acuerdo con la tercera cláusula, podemos escribir el código
 

 5. Sustitución de { } y [ ]

En algunos compiladores, como dev 5.11, podemos usar <: y :> en lugar de [ y ], y <% y %> en lugar de { y }.

#include <stdio.h>
int main() 
<%
	char a<::>="abcdefghigk";
	printf("%s",a);
	return 0;
%>

 6. Concatenación de cadenas

Cuando las cadenas rodeadas por "" se juntan, una cadena se empalmará automáticamente;

#include <stdio.h>
int main() {
	char* str = "aaaa""bbbb"\
				"cccc";
	printf("%s", str);
	return 0;
}

 7. Arreglos y nombres de arreglos

¿Realmente entiendes las matrices y los nombres de las matrices? Los nombres de las matrices pueden ser complicados. Por ejemplo, si defino una matriz int arr[10], ¿sabe qué significa arr? Después de leerlo, puede refrescar sus conocimientos sobre nombres de arreglos.

1. Representa la dirección del primer elemento, tenga en cuenta que representa la dirección del primer byte del primer elemento.

2. sizeof(arr) y &arr representan la dirección de la dirección completa (dos especiales)

#include <stdio.h>
int main() {
	int arr[10] = { 0 };
	printf("%p\n", arr);
	printf("%p\n", arr+1);
	printf("%p\n", &arr);
	printf("%p\n", &arr+1);
	return 0;
}

Imprime arr y &arr para encontrar que la dirección es la misma, debes recordar que la dirección es la misma pero su significado es muy diferente, arr es la dirección del primer elemento, arr+1 representa la dirección del segundo elemento, y el tamaño del paso es de 4 bytes.Es el tamaño del tipo int. Y &arr es la dirección de toda la matriz, y &arr+1 significa abarcar toda la matriz, con un tamaño de paso de 40, que es el tamaño de toda la matriz.

#include <stdio.h>
int main() {
	int arr[10] = { 0 };
	printf("%d\n",sizeof(arr));
	return 0;
}

 El valor de retorno de sizeof(arr) es de 40 bytes, lo que prueba que arr es la dirección de toda la matriz en este momento. La dirección que representa el grupo de enteros consta de estos dos casos especiales, y el resto de los casos representan la dirección del elemento receptor. ¿Crees que eso es todo? Aún no ha terminado.

#include <stdio.h>
int main() {
	int arr[10][10] = {0};
	printf("%d\n",sizeof(arr));
	printf("%d\n",sizeof(arr[0]));
	printf("%d\n",sizeof(arr[0][0]));
	return 0;
}

 ¿entender? arr es una matriz bidimensional, arr representa el tamaño de toda la matriz, por lo que es de 400 bytes, arr[0] representa el tamaño de la primera fila, por lo que es 40, arr[0][0] es el tamaño del primer elemento, por lo que es 4; sigamos observando.

#include <stdio.h>
int main() {
	int arr[10][10] = {0};
	printf("&arr:        %u\n", &arr);
	printf("&arr+1:      %u\n", &arr+1);
	printf("arr:         %u\n", arr);
	printf("arr+1:       %u\n", arr+1);
	printf("arr[0]:      %u\n", arr[0]);
	printf("arr[0]+1:    %u\n", arr[0]+1);
	printf("&arr[0]:     %u\n", &arr[0]);
	printf("&arr[0]+1:   %u\n", &arr[0]+1);
	printf("&arr[0][0]:  %u\n", &arr[0][0]);
	printf("&arr[0][0]+1:%u\n", &arr[0][0] + 1);

	return 0;
}

 

 &arr representa la dirección de toda la matriz, por lo que &arr+1 tiene un tamaño de paso de 400 y arr representa la dirección del primer elemento. Tenga en cuenta que la matriz es una matriz bidimensional y el primer elemento es de tipo 10 int números en la primera fila, por lo que el tamaño del paso es 40. arr[0] representa el primer elemento en el primer elemento de arr, que es a[0][0], por lo que el tamaño del paso es 4. &arr[0] representa todo el arr[0], por lo que el tamaño del paso es 40, &a[0][0] representa la dirección de la primera fila y la primera columna, y el tamaño del paso es 4. Puede ver que &arr, arr, arr[0], &a[0], &a[0][0] imprimen la misma dirección, pero sus significados son completamente diferentes. ¿Pensaste que era eso? Vamos.

#include <stdio.h>
int main() {
	int arr[3][4] = { 
		 {1,22,333,444},
		 {5,66,777,8888},
		 {99,130,113,123}
	};
	printf("&arr:\t%u\n", &arr);
	printf("&arr+1:\t%u\n", &arr+1);
	printf("*arr:\t%u\n", *arr);
	printf("*arr+1:\t%u\n", *arr+1);
	printf("**arr:\t%u\n", **arr);
	printf("**arr+1:\t%u\n", **arr+1);
	printf("*arr[2]:\t%u\n", *arr[2]);
	printf("*arr[2]:\t%u\n", *arr[2]+1);
	return 0;
}

 

 *arr representa todo el arr[0], ¿por qué? *arr=*(arr+0)=a[0] , comprenda, entonces el paso es el tamaño del elemento de una línea, es decir, 12 bytes, **arr representa a[0][0], porque *arr= un [0] ya se conoce. entonces             

**arr=*arr[0]=*(arr[0]+0)=a[0][0], el valor de a[0][0] es 1, por lo que se imprime como 1, seguido de 1 para representar el valor Sumar 1 no es una suma o resta de direcciones. Lo mismo ocurre con *arr[2]. ¿Pensaste que estaba hecho? No te preocupes, hay más.

#include <stdio.h>
int main()
{
	int i, j;
	int arr[3][4] = { 1,22,3333,4,55,666,7,88,999,101,1167,12242 };
	
	printf("*(arr+4*i+j)\n");
	for (i = 0; i < 3; i++) {
		for (j = 0; j < 4; j++) {
			printf("%d   ",**(arr + 4 * i + j));
		}

	}
	printf("\n");
	for (i = 0; i < 3; i++) {
		for (j = 0; j < 4; j++) {
			printf("%d   ",**arr + 4 * i + j);
		}
	}
	return 0;
}

 **(arr + 4 * i + j), arr representa el primer elemento y el tamaño del paso es de 12 bytes de una fila de elementos, por lo que los tres primeros son los primeros elementos de cada fila y la dirección posterior está fuera de límites y es un valor aleatorio. **arr + 4 * i + j, **arr también es arr[0][0], así que suma 1 cada vez. Sigamos viendo.

 

#include <stdio.h>
int main()
{
	int i, j;
	int arr[3][4] = { 1,22,3333,4,55,666,7,88,999,101,1167,12242 };
	for (i = 0; i < 3; i++) {
		for (j = 0; j < 4; j++) {
			printf("arr[%d][%d]=%d\t", i, j, *(&arr[0][0] + 4 * i + j));
		}
		printf("\n");
	}
	printf("\n");
	for (i = 0; i < 3; i++) {
		for (j = 0; j < 4; j++) {
			printf("arr[%d][%d]=%d\t", i, j, *(*(i + arr) + j));//i[a][j]
		}
		printf("\n");
	}
	return 0;
}

  *(&arr[0][0] + 4 * i + j), tome el tamaño de paso de la dirección del elemento de la primera fila y la primera columna como 1, luego agregue 1 para eliminar la referencia e imprima todos los valores de la matriz. *(*(i + arr) + j) es en realidad a[i][j], ¿cómo lo preguntaste? a[i][i]=*(a[i]+j)=*(*(arr+i)+j) , muy simple, ¿verdad? Solo aquí puedo atreverme a decir que estoy familiarizado con la aplicación de nombres de matrices, preste atención a la familiaridad. 

Supongo que te gusta

Origin blog.csdn.net/m0_73731708/article/details/130920173
Recomendado
Clasificación