Указатели
.pdfУказатели
Указатели
Указатель (pointer) - это переменная, хранящая адрес области памяти
Типы указателей соответствуют типам переменных: char* pchar;
int* pint;
double * pdouble; float *pfloat
& - взятие адреса
* - разыменование указателя. Если pvar - указатель на переменную var, то *var - значение переменной
Пример
#include <stdio.h> int main(void)
{
int j, k; int *ptr; j = 1;
k = 2; ptr = &k;
printf("\n");
printf("j has the value %d and is stored at %p\n", j, &j); printf("k has the value %d and is stored at %p\n", k, &k); printf("ptr has the value %p and is stored at %p\n", ptr, &ptr); printf("The value of the integer pointed to by ptr is %d\n", *ptr); return 0;
}
Массив
Имя массива является указателем на его первый элемент
a[i] эквивалентно *(a+i) (и, в принципе, эквивалентно i[a])
int a[3] = {0, 1, 2};
int b[2][5] – две строки, пять столбцов
a[0] |
a[1] |
a[2] |
a[3] |
|
|
|
|
|
|
|
|
*a *(a+1) |
*(a+2) |
*(a+3) |
#include <stdio.h> #include <stdlib.h> int main()
{
int rows = 5; int cols = 10; int i;
int **a;
a= malloc(rows * sizeof(int *)); if (a == NULL) {
puts("\nFailure to allocate room for i pointers.\n"); exit(0);
}
printf("\n\n\nIndex Pointer(hex) Pointer(dec) Diff.(dec)");
for (i = 0; i < rows; i++) {
a[i] = malloc(cols * sizeof(int));
printf("\n%d %p %d", i, a[i], a[i]); if (i > 0)
printf("%d", (int)(a[i] - a[i-1]));
}
putchar('\n'); return 0;
}
Упражнение: заполнить этот массив: aij = i + j и вывести на экран
Функции и массивы
Функция, возвращающая скалярное произведение массивов:
int scalar_prod(int n, int* a, int* b)
Выделить память под матрицу: int** allocate_matr(int n, int m);
Произведение матриц:
void mult (int n, int m, int **a, int *res)
Упражнение: запрограммируйте их и напишите тест, демонстрирующий работу.
Указатель на функцию
Примеры объявлений:
int |
sum(double a, double b); |
int |
sub(double, double); |
void* |
pf(const int m, int k); |
double (*pf)(int*, int*, char*); float* (*(*func)(int))[10]
Имя функции является указателем на «точку входа».
|
void f(int x, double &a) |
void (*foo)(int, double) |
{ |
|
a >>=x; |
“f” является переменной типа “foo” |
} |
|
|
|
Пример + упражнение
#define FUNC(x) ((*func)(x))
double trapzd(double (*func)(double), double a, double b, int n)
{
double x,tnm,sum,del; static double s;
int it,j;
if (n == 1) {
return (s=0.5*(b-a)*(FUNC(a)+FUNC(b))); } else {
for (it=1,j=1;j<n-1;j++) |
Эта функция вычисляет интеграл от a до |
|
it <<= 1; |
||
b (см. Numerical Recipes in C). Написать |
||
tnm=it; |
||
для нее тест. |
||
del=(b-a)/tnm; |
||
|
||
|
x=a+0.5*del;
for (sum=0.0,j=1; j<=it; j++,x+=del) sum += FUNC(x);
s=s+(b-a)*sum/tnm; return s;
}
}
Строки
#include <stdio.h>
char strA[80] = "A string to be used for demonstration purposes";
char strB[80]; |
|
int main(void) |
|
{ |
|
char *pA; |
<сstring> содержит большое количество функций для |
char *pB; |
работы со строками |
puts(strA); |
См., напр., http://www.cplusplus.com/reference/cstring/ |
pA = strA; |
|
|
|
puts(pA); |
|
pB = strB; |
|
putchar('\n'); |
|
while(*pA != '\0') |
|
*pB++ = *pA++; |
|
*pB = '\0'; |
|
puts(strB); |
|
return 0; |
|
} |
|
#include <stdio.h> |
Указатели на структуру |
|
#include <string.h> |
||
|
||
struct tag{ |
|
|
char lname[20]; |
|
|
char fname[20]; |
|
|
int age; |
|
|
float rate; |
|
|
}; |
|
struct tag my_struct;
void show_name(struct tag *p);
int main(void)
{
struct tag *st_ptr; st_ptr = &my_struct;
strcpy(my_struct.lname, "Jensen"); strcpy(my_struct.fname, "Ted"); printf("\n%s ", my_struct.fname); printf("%s\n", my_struct.lname); my_struct.age = 63; show_name(st_ptr);
return 0;
}
Вместо
(*st_ptr).age = 63;
пишут
st_ptr->age = 63;
void show_name(struct tag *p)
{
printf("\n%s ", p->fname); printf("%s ", p->lname); printf("%d\n", p->age);
}