Con respecto a lo que es un puntero, puede consultar la columna C elemental 5. Publicación de blog de punteros y variables de puntero
Transferencia de parámetros de matriz unidimensional
Transferencia de parámetros de matriz bidimensional
Tres punteros de función y funciones de devolución de llamada
Matriz de punteros de cuatro funciones
Cinco preguntas comunes de la entrevista
Puntero de matriz
Puntero a la matriz, la variable de puntero almacena la dirección de la matriz 1
#include <stdio.h>
int main() {
int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int(*ptr_int)[10] = &arr;
printf("%d\n", ((int*)(ptr_int + 1))[-1]);
// 数组指针向后偏移一个单位就相当于偏移整个数组长度个单位量
return 0;
}
Cabe señalar que: el puntero de la matriz desplazado hacia atrás una unidad es equivalente a la dirección desplazada por la cantidad total de unidades de longitud de la matriz
También es necesario tener en cuenta que los punteros de matriz deben usarse para la transferencia de parámetros de matriz:
Transferencia de parámetros de matriz unidimensional
#include <stdio.h>
void test(int arr[10], int size)//ok?
{
for (int i = 0; i < size; ++i)
printf("%d ", arr[i]);
printf("\n");
}
void test1(int arr[], int size)//ok?
{
for (int i = 0; i < size; ++i)
printf("%d ", arr[i]);
printf("\n");
}
void test2(int* arr, int size)//ok?
{
for (int i = 0; i < size; ++i)
printf("%d ", arr[i]);
printf("\n");
}
void test3(int* arr_ptr[10], int size)//ok?
{
for (int i = 0; i < size; ++i)
printf("%d ", *arr_ptr[i]);
printf("\n");
}
void test4(int** arr_ptr, int size)//ok?
{
for (int i = 0; i < size; ++i)
printf("%d ", *arr_ptr[i]);
printf("\n");
}
int main()
{
int arr[10] = { 0 };
for (int i = 0; i < 10; ++i)
arr[i] = i + 1;
int* arr_ptr[10] = { 0 };
for (int i = 0; i < 10; ++i)
arr_ptr[i] = arr + i;
test(arr, 10);
test1(arr, 10);
test2(arr, 10);
test3(arr_ptr, 10);
test4(arr_ptr, 10);
return 0;
}
test~test2都是一维整形数组传参方式,int arr[元素个数]、int arr[]、 int* arr;
test3~4是整形指针数组的传参方式,int* arr_ptr[元素个数]、int* *arr_ptr;
Transferencia de parámetros de matriz bidimensional
#include <stdio.h>
void test1(int arr[3][5], int row, int column)//ok?
{
for (int i = 0; i < row; ++i){
for (int j = 0; j < column; ++j)
printf("%d ", arr[i][j]);
printf("\n");
}
printf("\n");
}
void test2(int arr[][5], int row, int column)//ok?
{
for (int i = 0; i < row; ++i) {
for (int j = 0; j < column; ++j)
printf("%d ", arr[i][j]);
printf("\n");
}
printf("\n");
}
//总结:二维数组传参,函数形参的设计只能省略第一个口的数字。
void test3(int* arr, int row, int column)//ok?
{
for (int i = 0; i < row; ++i) {
for (int j = 0; j < column; ++j)
printf("%d ", (arr + i * 5)[j]);
printf("\n");
}
printf("\n");
}
void test4(int* arr[5], int row, int column)//ok?
{
for (int i = 0; i < row; ++i) {
for (int j = 0; j < column; ++j)
printf("%d ", (arr+i*5)[j]);
printf("\n");
}
printf("\n");
}
void test5(int(*arr)[5], int row, int column)//ok?
{
for (int i = 0; i < row; ++i) {
for (int j = 0; j < column; ++j)
printf("%d ", arr[i][j]);
printf("\n");
}
printf("\n");
}
void test6(int** arr, int row, int column)//ok?
{
for (int i = 0; i < row; ++i) {
for (int j = 0; j < column; ++j)
//printf("%d ", (arr + i * 5)[j]);
printf("%d ", arr[i * 5][j]);
printf("\n");
}
printf("\n");
}
int main() {
int arr[3][5] = { 0 };
for (int i = 0; i < 3; ++i)
for (int j = 0; j < 5; ++j)
arr[i][j] = i*5 + j;
test1(arr, 3, 5);
test2(arr, 3, 5);
test3(arr, 3, 5);
test4(arr, 3, 5);
test5(arr, 3, 5);
test6(arr, 3, 5);
return 0;
}
Test1 ~ test6 puede completar el proceso de transferencia de parámetros de matriz bidimensional
Matriz de punteros
Matriz de punteros
#include <stdio.h>
int main() {
int a=1, b=2, c=3, d=4;
int* arr_ptr[4] = { &a, &b, &c, &d };
for (int i = 0; i < 4; ++i)
printf("%d\n", *arr_ptr[i]);
return 0;
}
La matriz de punteros arr_ptr almacena punteros de tipo int *
Puntero de función y función de devolución de llamada
Puntero de función: puntero a función
Definir una función de comparación para dar forma a elementos.
int compare (const void arg1, const void arg2) { return (int ) arg1-
(int ) arg2;
}
Definir un puntero de función para comparar
int * ptr_func (const void * arg1, const void * arg2) = comparar;
Llamar de vuelta
Una función de devolución de llamada es una función llamada a través de un puntero de función. Si pasa un puntero de función (dirección) como parámetro a otra función, cuando este puntero se usa para llamar a la función a la que apunta, decimos que se trata de una función de devolución de llamada. La función de devolución de llamada no es llamada directamente por el implementador de la función, pero es llamada por otra parte cuando ocurre un evento o condición específica, y se usa para responder al evento o condición.
Regala una castaña:
El último parámetro de la función de clasificación rápida qsort definida en <stdlib.h> y <search.h> requiere la dirección de función de una función de comparación
qsort ((void *) argv, (size_t) argc, sizeof (char *), compare);
El primer parámetro de la función de clasificación rápida qsort es la primera dirección del espacio a ordenar, el segundo parámetro argc es el número de elementos, el tercer parámetro es el tamaño en bytes de un elemento y el tercer parámetro es el tamaño del elemento proporcionado por el usuario. Función de comparación
#include <stdio.h>
int compare(const void* arg1, const void* arg2) {
return *(int*)arg1 - *(int*)arg2;
}
int main() {
int (*ptr_func)(const void* , const void* ) = compare;
int arr[] = { 4, 6, 3, 1, 9, 8, 5, 2 };
int args = sizeof(arr) / sizeof(int);
qsort((void*)arr, args, sizeof(int), ptr_func);
for (int i = 0; i < args; ++i)
printf("%d ", arr[i]);
printf("\n");
return 0;
}
Matriz de punteros de función
En términos sencillos, es una matriz de punteros de función
Avión pequeño BC6
Modo de matriz de puntero de función:
#include <stdio.h>
void func1(){
printf(" ** \n");
}
void func2(){
printf("************\n");
}
void func3(){
printf(" * * \n");
}
int main()
{
void (*p[3])() = {
func1, func2, func3};
for(int i=0; i<3; ++i){
p[i]();
p[i]();
}
return 0;
}
Formato de definición de matriz de puntero de función: valor de retorno de función + (* nombre de matriz de puntero) + (lista de parámetros) + lista de inicialización
Preguntas comunes de la entrevista
Prueba escrita 1:
int main()
{
int a[5] = { 1, 2, 3, 4, 5 };
int *ptr = (int *)(&a + 1);
printf("%d, %d" *(a + 1), *(ptr - 1));
return 0;
}
// ¿Cuál es el resultado del procedimiento?
2, 5
Prueba escrita 2:
// A través del conocimiento de la alineación de la memoria, podemos calcular el tamaño de la prueba de estructura en 20
#include <stdio.h>
struct Test
{
int Num;
char pcName;
short sDate;
char cha[2];
short sBa[4];
}*p;
//假设p的值为0x100000。如下表表达式的值分别为多少? int main()
int main() {
printf("%p\n", p + 0x1);
printf("%p\n", (unsigned long)p + 0x1);
printf("%p\n", (unsigned int*)p + 0x1);
return 0;
}
p + 0x1, la dirección del puntero está compensada por una unidad, está compensada por el tamaño del byte de estructura 0x100014
(unsigned long) p + 0x1 se convierte primero a la fuerza en cuatro bytes de longitud sin firmar, sin importar si el truncamiento ocurre en una plataforma de 32 o 64 bits, el valor final es 0x100001
(unsigned int *) p + 0x1 Primero fuerce el puntero de estructura a un puntero entero sin signo, agregue uno, la dirección está compensada por cuatro bytes y finalmente: 0x100004
Pregunta de prueba escrita 3:
int main()
{
int a[4] = { 1, 2, 3, 4 );
int *ptrl = (int *)(&a + 1);
int *ptr2 = ((int)a + 1);
printf("%x,%x”, ptrl[-l], *ptr2);
return 0;
}
apagar:
4, 00000003 2
Prueba escrita 4:
#include <stdio.h>
int main()
{
int a[3][2] = { (0, 1), (2, 3), (4, 5) };
int *p;
p = a[0];
printf("%d", p[0]);
return 0;
}
1
Pregunta de prueba escrita 5:
int main()
{
int a[5][5];
int(*p)[4];
p = a;
printf( "%p,%d\n", &p[4][2]-&a[4][2], &p[4][2] - &a[4][2]);
return 0;
}
& p [4] [2] - & a [4] [2] = -4 se convierte en complemento hexadecimal 10000… 100 11111… 011 11111… 100 = FFFFFFFC
FFFFFFFC, -4
Pregunta escrita 6:
#include <stdio.h>
int main() {
int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int* ptrl = (int*)(&aa + 1);
int* ptr2 = (int*)(*(aa + 1));
printf("%d,%d", *(ptrl - 1), *(ptr2 - 1));
return 0;
}
10,5
Pregunta de prueba escrita 7:
#include <stdio.h>
int main()
{
char* a[] = { "work", "at", "alibaba"};
char** pa = a;
pa++;
printf("%s\n", *pa);
return 0;
}
a
Pregunta de prueba escrita 8:
#include <stdio.h>
int main() {
char* c[] = { "ENTER","NEW","POINT","FIRST" };
char **cp[] = {c + 3, c + 2, c + 1, c};
char*** cpp = cp;
printf("%s\n", **++cpp);
printf("%s\n", *-- * ++cpp + 3);
printf("%s\n", *cpp[-2] + 3);
printf("%s\n", cpp[-1][-1] + 1);
return 0;
}
POINT ER ST EW
** ++ cpp, la prioridad pre - ++ es mayor que *. Primero ++ cpp, cpp es la dirección, se convierte en la dirección del elemento c + 2, y dos ** para obtener la dirección del primer elemento de "PUNTO"
* - * ++ cpp, la prioridad pre - ++ es mayor que * y la pre-precedencia es mayor que *. ++ cpp, cpp guarda la dirección de c + 1, después de eliminar la referencia, obtenga la dirección del elemento c
* cpp [-2], [] tiene una prioridad más alta que *. cpp [-2], obtener c + 3 elemento, desreferenciar para obtener la primera dirección de "FIRST", +3 es ST
cpp [-1] [- 1] + 1. cpp [-1] obtiene la dirección del elemento c + 2, luego [-1] obtiene la primera dirección de "NUEVO", luego +1, obtiene EW