Здравствуйте, Сергей. Очень надеюсь, что на основе этой серии роликов вы сделаете курс на степик, подобно вашему великолепному курсу по пайтону (и ООП)
По вопросу передачи двухмерного массива в функцию и второго сбособа (использование одномерного массива вместо двухмерного). Можно сделать по-другому, не менять исходный массив на одномерный, а кастить и передавать двухмерный массив в функцию как одномерный (int*). Оно и логично, зачем заменять двухмерный массив одномерным, если в памяти двухмерный (статический) массив и так располагается как одномерный. А внутри функции адреса элементов массива вычислять через адресную арифметику. Например: void func(int *ar, int rows, int cols) { for (int j=0; j < rows; ++j) for (int i=0; i < cols; ++i) printf("%d", *(ar + cols*j + i)); } int main() { int a[][3] = { {1, 2, 3}, {5, 6, 7} }; func( (int*)a, 2, 3); return 0; }
а подскажи чем такой вариант лучше/хуже чем передача указателя на первый подмассив с укзаанием кол-ва "строк" или чем использование одномерного массива? void print_arr2D(int rows, int cols, int arr[rows][cols]) { for(int i = 0; i < rows; i++) { for(int j = 0; j < cols; j++) { printf("%d ", arr[i][j]); } putchar(' '); } } int main() { int arr[3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}; print_arr2D(3, 4, arr); return 0; }
Я видимо тупой, но как работают указатели в сях я понял только после того, как немного разобрался с ассемблером x86, с различными спосоьами адресации. Прям как пазл сложился, после того как вкурил тему с 'указателями' в асм.
Функция find_space возвращает указатель на первый пробел строки, но что она возвратит, если пробелов в строке нет? Ведь тогда цикл while завершается при достижении символа \0 в конце строки , а потом завершается вся функция без определения возвращаемого значения. Результат функции в этом случае неопределен. Лучше предусмотреть такой случай и сделать, чтобы функция вернула, например, пустой указатель, как знак, что пробел не найден. Для этого достаточно в конце функции написать оператор "return NULL;"
Может вопрос еще не по теме, однако, как достучаться до локальной переменной в прерывании не создавая глобальных? //таймер по переполнению ISR (TIM0_OVF_vect) { ++a; //ругается на область видимости🤔 } int main(void) { static int a=5; while(1) { asm("cli"); if(a>30) a=5; asm("sei"); } return 0; }
@@yore4226 t и есть промежуточная переменная через которую и происходит обмен, что не требуется в питоне, не пойму ваш комент о чём. Может вы как то мою речь трактуете не так, не понимаете сложных форм, я проверил её, все знаки препинания на месте.
@@mslq Странно, но при прочтении, смысл вашего комментария, в моей голове, получается строго обратный. С вашим дополнением все встало на место. Звиняйте. З.Ы. А запятых, если что, малость не хватает. :)
@@nickname5906 ну питон я так понял написан для человеков, а не для машины, он человечный, добрый, отзывчивый, понятный. По этому и не нужна промежуточная переменная, А СИ это тот же ACM, только весь в макро, у меня самого всё в макросах, на ATmega пишу, си не признаю.
единственный человек в ютубе, кто смог это тему втолдычить :) в голову спасибо большущее!!
Spasibo вам большое за такой склад информации!
Спасибо. Восторг!
Здравствуйте, Сергей. Очень надеюсь, что на основе этой серии роликов вы сделаете курс на степик, подобно вашему великолепному курсу по пайтону (и ООП)
По вопросу передачи двухмерного массива в функцию и второго сбособа (использование одномерного массива вместо двухмерного). Можно сделать по-другому, не менять исходный массив на одномерный, а кастить и передавать двухмерный массив в функцию как одномерный (int*). Оно и логично, зачем заменять двухмерный массив одномерным, если в памяти двухмерный (статический) массив и так располагается как одномерный. А внутри функции адреса элементов массива вычислять через адресную арифметику.
Например:
void func(int *ar, int rows, int cols)
{
for (int j=0; j < rows; ++j)
for (int i=0; i < cols; ++i)
printf("%d", *(ar + cols*j + i));
}
int main()
{
int a[][3] = { {1, 2, 3}, {5, 6, 7} };
func( (int*)a, 2, 3);
return 0;
}
спасибо за видео!!
скажите пожалуйста, зачем столько const char* -ов ?😰
Const char* - это можно сказать строка, если по другому то компилятор будет переменную воспринимать как не строку
а подскажи чем такой вариант лучше/хуже чем передача указателя на первый подмассив с укзаанием кол-ва "строк" или чем использование одномерного массива?
void print_arr2D(int rows, int cols, int arr[rows][cols])
{
for(int i = 0; i < rows; i++) {
for(int j = 0; j < cols; j++) {
printf("%d ", arr[i][j]);
}
putchar('
');
}
}
int main() {
int arr[3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
print_arr2D(3, 4, arr);
return 0;
}
тут, скорее, дело удобства, и ваше решение хорошее
Я видимо тупой, но как работают указатели в сях я понял только после того, как немного разобрался с ассемблером x86, с различными спосоьами адресации. Прям как пазл сложился, после того как вкурил тему с 'указателями' в асм.
да на таком уровне разницы кода между асмом и сями нет )
люблю асм, только сейчас меговский юзаю, пришлось питон учить, нужно приложение в компе чтобы девайсу товарный вид придать.
Функция find_space возвращает указатель на первый пробел строки, но что она возвратит, если пробелов в строке нет? Ведь тогда цикл while завершается при достижении символа \0 в конце строки , а потом завершается вся функция без определения возвращаемого значения. Результат функции в этом случае неопределен. Лучше предусмотреть такой случай и сделать, чтобы функция вернула, например, пустой указатель, как знак, что пробел не найден. Для этого достаточно в конце функции написать оператор "return NULL;"
Согласен!
Может вопрос еще не по теме, однако, как достучаться до локальной переменной в прерывании не создавая глобальных?
//таймер по переполнению
ISR (TIM0_OVF_vect)
{
++a; //ругается на область видимости🤔
}
int main(void)
{
static int a=5;
while(1)
{
asm("cli");
if(a>30) a=5;
asm("sei");
}
return 0;
}
надо как то адрес переменной передавать в функцию, по другому - никак
А в чем проблема сделать 'a' глобальной? Другого пути здесь нет.
Можно, но постоянно говорят про дурной тон программирования, вот я решил спросить😁
@@АндрейИванов-е6о4т ничего дурного тут нет, если делать с умом)
Это блин не питон, чтобы без промежуточной переменной обменять значения в ячейках ))
т.е. вы не заметили на экране строчку:
int t = a;
да и в питоне все делается без каких-то новых переменных, если мы говорим про ячейки памяти.
@@yore4226 t и есть промежуточная переменная через которую и происходит обмен, что не требуется в питоне, не пойму ваш комент о чём. Может вы как то мою речь трактуете не так, не понимаете сложных форм, я проверил её, все знаки препинания на месте.
@@mslq Странно, но при прочтении, смысл вашего комментария, в моей голове, получается строго обратный. С вашим дополнением все встало на место. Звиняйте.
З.Ы. А запятых, если что, малость не хватает. :)
значит на уровне транслятора вводится промежуточная переменная, а по другому на физическом уровне никак
@@nickname5906 ну питон я так понял написан для человеков, а не для машины, он человечный, добрый, отзывчивый, понятный. По этому и не нужна промежуточная переменная, А СИ это тот же ACM, только весь в макро, у меня самого всё в макросах, на ATmega пишу, си не признаю.
А почему нельзя просто передавать указатель на массив как const char** и вместе с тем просто две переменные размеров? типа int x и int y.
это будет указатель на указатель