programming

Указатели

const int a = 4;
const int *ptr &a; - указатель на константу \*ptr

int a = 4;
int * const ptr = &a - константный указатель

array name ~ &a[0]
&a - указатель на массив длины 10

int (*b)[10] = &a; -
int *ptr;
ptr++;

typedef int x;
x a=10;

перемещение по массиву с шагом

int (*b)[10] - b - указатель на массив из 10 int
typedef int (*b)[10]; - описание типа
b ptr;
int aa[20];
ptr = (b)aa;
ptr -> start
ptr + 1 -> middle

01…10…1920
ptrptr+1

char *S[10] - массив указателей char длины 10
char** S ~ char *S[]

int main(int argc, char** argv) {}
gcc prog.c -o prog - аргументы в gcc попадают так

input

prog.out -a/-b/-c

argc - count of args and argv is args

int main(int argc, char** argv)
{
	char mode = argv[1][0];
	switch(mode)
	{
		case 'a': ...;
		break;
		case 'b': ...;
		break;
		...
		default: printf("Unknown mode\n");
		break;
	}
}

Чётные числа

int a = {10, 13, 24, 5, 7};
int len = sizeof(a) / sizeof(int);
int i;
for(i = 0; i < len; i++)
{
	if (!(a[i]%2))
		continue;
	...
}

Указатель на функцию

например вычисление значения функции при её интегрировании

int *f(int a); - func retuns pointer
int (*f)(int a); - pointer to func takes int and retuns int

integrator (double a; double b; double (*f)(double x));
double parabola(double x)
	{return x*x + 2*x - 3}
integrator (0.0, 1.0, parabola);
(0, 1, ...)

Битовые операции

Нужны для доступа к отдельным битам

Атрибуты файла

Права доступа

r - право на чтение
w - право на запись
x - право на запуск
- - null

namex2x8x10x16
rwx111\07640xAB
r1004
0102
0011

Группы пользователей

  • Владелец файла
  • Группа владельца
  • Остальные

Операции

nameboolbit
and&&&
or|||
xor!=^
not!~
a = a<<2, a <<= 2 - rol
a = a>>2, a >>= 2 - ror

Применение

  • & - сброс флажка (clear)
  • | - установка флажка (set)
  • ^ - инвертация флажка
int clearFlag(undigned char*pack; int n)
{
	if (n < 0 || n > 7)
		return -1;
	if (!pack)
		return 2;
	unsigned char mask = 1 << n;
	mask ~= mask; // not and assign
	*pack &= mask;
	return 0;
}

меняем n-й бит unsigned char

// exchange values
x = x^y;
y = y^x; // -> y = x^y^y=x^0=x;
x = x^y;

ещё пример (поменять местами половины байта)

int swap_hlv(unsigned char* byte)
{
	if (byte == NULL)
		return 1;
	
	unsigned char mask = 1<<4;
	mask = mask - 1;
	
	*byte = (*byte & mask) << 4 + (*byte & ~mask) >> 4;
	return 0;
}

// 0101 1111 -> 1111 0101

посчитать количество 1 в байте

int count_ones(unsigned char*byte; int* error)
{
	if (!byte)
	{
		*error = 1;
		return 0;
	}
	unsigned char temp = *byte;
	
	int count = 0;
	for (int i=0; i<sizeof(char); i++)
	{
		count += *temp&1;
		*temp>>1;
	}
	return count;
}

метод Кернигана

int count_Kernigan()
{
	unsigned int v; // 1 inside
	undigned int c; // count of 1
	
	for (c=0; v; c++)
	{
		v &= v-1;
	}
}